C语言学习之字符串,字符,字节,结构和联合
1. 字符串
字符串就是一串零个或多个字符,并且以一个位模式全为0的NUL字节结尾。
头文件string.h包含了使用字符串函数所需要的原型和声明。
memxxx函数提供了累死你字符串函数的能力,但是可以处理包括NUL字节在内的任意字节。
2. 结构和联合
结构也是一些值得集合,这些值也称之为它的成员,但是一个结构的各个成员可能具有不同的类型。结构不能通过下标来访问他们,每个结构成员都有自己的名字,他们是通过名字访问的。结构变量无法使用下标来选择特定的成员。结构变量属于标量类型。
在声明结构时,必须列出它包含的所有成员,这个列表包括每个成员的类型和名字:
struct tag{ member-list} variable-lsit; 如:
struct {
int a;
int b;
int c;
} y[20], *z; 直接声明
或者
struct SIMPLE{
int a;
char b;
float c;
};
struct SIMPLE x;
struct SIMPLE y[20], *z; 标签
标签标识了一种模式,用于声明未来的变量,但是无论是标签还是模式,其本身都不是变量。
声明结构时可以使用的另一种良好技巧是用typedef创建一种新的类型,如下:
typedef struct{
int a;
char b;
float c;
}simple;
simple x;
simple y[20], *z;
如果想要在多个源文件中使用同一种类型的结构,就应该把标签声明或typedef形式的声明放在一个头文件中。如果源文件需要这个声明,可以使用#include指令把那个头文件包含进来。
结构成员可以是标量,数组,指针甚至是其他结构。
结构成员的直接访问。结构变量的成员是通过点操作符(.)访问的。
结构成员的间接访问。如果你拥有一个指向结构的指针,首先需要对指针执行间接访问操作,从而获得这个结构,然后再使用点操作符来访问它的成员。如
void func( struct COMPLEX *cp);
(*cp).f
箭头操作符(->)和点操作符一样,箭头操作符接受两个操作数,但左操作数必须是一个指向结构的指针,箭头操作符对左操作数执行间接访问取得指针所指向的结构,然后和点操作符一样,根据右操作数选择一个指定的结构成员。如:
cp->f
结构的自引用:
struct SELF_REF1{
int a;
struct SELF_REF1 b;
int c;
};
这种类型的自引用是非法的,中间自引用的b是另外一个完整的结构,它会一直递归下去。整个结构体的长度是确定不了的。
struct SELF_REF1{
int a;
struct SELF_REF1 *b;
int c;
};
编译器在结构长度确定在之前就已经知道指针的长度,所以这种类型自引用是合法的。
结构的初始化:一个位于一对花括号内部,由逗号分隔的初始值列表可用于结构中各个成员的初始化。这些值根据结构成员列表的顺序写出,如果初始列表的值不够,剩余的结构成员将使用缺省值进行初始化。
结构体数据存储的对齐规则:所有的成员在分配内存时都要与所有成员中占内存最多的数据类型所占内存空间的字节数对齐。假如这个字节数为 N,那么对齐的原则是:理论上所有成员在分配内存时都是紧接在前一个变量后面依次填充的,但是如果是“以 N 对齐”为原则,那么,如果一行中剩下的空间不足以填充某成员变量,即剩下的空间小于某成员变量的数据类型所占的字节数,则该成员变量在分配内存时另起一行分配。
作为函数参数的结构体:
typedef struct{
char product[PRODUCT_SIZE]};
int quantity;
float uint_price;
float total_amount;
} Transaction;
void print_receipt(Transaction trans)
{
printf("%s\n", trans.product);
printf("%d@%.2f total %.2f\n", trans.quantity, trans.uint_prince,trans.total_amount);
}
这种方式能够产生正确的结果,但它的效率很低,因为C语言的参数传值调用方式要求把参数的一份副本传递给函数。如果PRODUCT_SIZE的值为20,而且我使用的机器上整数和浮点数都占4字节,那么这个结构将占据32字节的空间。要想把它作为参数进行传递,则必须把32字节复制到堆栈中,以后再丢弃。
void print_receipt(Transaction *trans)
{
printf("%s\n", trans->product);
printf("%d@%.2f total %.2f\n", trans->quantity, trans->uint_prince,trans->total_amount);
}
如果传递给函数的屙屎一个指向结构的指针,指针比整个结构要小得多,所以把它压到堆栈上效率能高得多。这种方式的缺陷在于函数现在可以对调用程序的结构变量进行修改。如果不希望如此,可以用const关键字来防止此类修改。
void print_receipt(register Transaction const *trans)
{
printf("%s\n", trans->product);
printf("%d@%.2f total %.2f\n", trans->quantity, trans->uint_prince,trans->total_amount);
}
位段:位段的声明和结构类似,但它的成员是一个或多个位的字段,这些不同长度的字段实际上存储于一个或多个整型变量中。位段成员必须声明为int,singned int或unsigned int类型。其次,在成员名的后面是一个冒号和一个整数,这个整数指定该位段所占用的位的数目。
注重可移植性的程序应该尽量避免使用位段。
struct CHAR {
unsigned ch : 7;
unsigned font : 6;
unsigned size : 19;
};
struct CHAR ch1;
使用位段只是基于方便的目的,任何可以用位段实现的任务都可以使用移位和屏蔽来实现。
联合
联合的声明和结构类似,但它的行为方式却和结构不同。联合的所有成员引用的是内存中相同的位置,如果想把在不同的时刻把不同的东西存储于同一个位置就可以使用联合。如:
union {
float f;
int i;
}fi;
在一个浮点型和整形都是32位的机器上,变量fi只占据内存中一个32位的字,如果成员f被使用,这个字就作为浮点值访问,如果成员i被使用,这个值就作为整型值访问。
如果联合的各个成员具有不同的长度,联合的长度就是它最长成员的长度。如果这些成员长度相差悬殊,当存储长度较短的成员时,浪费的空间时相当可观的。子这种情况下,更好的办法是在联合中存储指向不同成员的指针而不是直接存储成员本身。
联合的初始化
联合变量可以被初始化,但这个初始值必须是联合第一个成员的类型,而且它必须位于一对花括号里面,如:
union {
int a;
float b;
char c[4];
}x = { 5 };
C语言学习之字符串,字符,字节,结构和联合相关推荐
- Python语言学习之字符串那些事:python和字符串的使用方法之详细攻略
Python语言学习之字符串那些事:python和字符串的使用方法之详细攻略 目录 python与字符串的那些事 1.字符串中只保留汉字 2.字符串的截取 3.在字符串中加入变量 4.字符串与列表转换 ...
- C语言学习Day1 字符串
概念:C语言中没有字符串数据类型,对于字符串的存储是通过 字符数组 来实现的.可以理解为一个以'\0'字符结尾的字符数组,而'\0'表示字符串的结束. 1.字符串的初始化 字符串定义时可以使用 &qu ...
- C语言学习笔记——字符串结束符\0
C语言中的字符串结束符\0标志着字符串的结束,由编译器自己加上的,ASCII值为0,表示NULL,ASCII中有很多不可见字符由转义字符\和可见字符来标识的,当然可见字符也能用转义字符表示.
- go struct 静态函数_Go语言学习笔记(四)结构体struct 接口Interface 反射reflect...
加 Golang学习 QQ群共同学习进步成家立业工作 ^-^ 群号:96933959 结构体struct struct 用来自定义复杂数据结构,可以包含多个字段(属性),可以嵌套: go中的struc ...
- C语言学习笔记——使用字符数组和实型数组分别存储学生姓名和成绩,并通过对学生成绩的排序,按名次输出
题目来自C语言从入门到精通第三版:使用字符数组和实型数组分别存储学生姓名和成绩,并通过对学生成绩的排序,按照名次输出字符数组中对应的学生姓名 在网上大致找了一下没有看到C语言实现的版本,于是自己写了一 ...
- C 语言里的字符串---字符数组
// 实际上, c中并没有字符串这种数据类型, 也就是说c是没有像java, .net等其他高级语言中常用的String类型. 首先要强调: a. c语 ...
- C语言学习笔记---字符串查找函数strstr()和strpbrk()函数
strstr()函数 C语言中如何向查找一个字符串中是否包含另一个字符串,可以使用strstr()函数.使用示例如下: int main(int argc, char *argv[]) {char ...
- go语言学习(3)面向对象,结构体和方法
感觉每种语言都是其他的语言的一些交集,看见go就有种kotlin和C的孩子的感觉,虽然我并不清楚他们之间的借鉴关系 go语言仅支持封装,不支持继承和多态 go语言只有struct没有class go语 ...
- C语言学习笔记---字符串转换函数
字符串转整数 字符串转换为整数的函数有两个,他们的函数原型如下: int __cdecl atoi(const char *_Str);long __cdecl atol(const char * ...
最新文章
- angularjs 学习笔记 简单基础
- 用YOLOv5模型识别出表情!
- Matlab读取文本数据
- 【软考-软件设计师】计算机安全
- 浅析epoll-为何多路复用I/O要使用epoll
- 什么是Kibana?Kibana安装与配置(win_Elasticsearch)
- netty系列之:内置的Frame detection
- IDEA 将 SpringBoot 项目打包成jar
- Spring Cloud Config 规范
- 郑州大学linux试题,郑州大学Linux讲义 PPT
- 运维小白的成长日记第四天-基础网络构建OSI七层模型-物理层基础知识
- 2021-09-09
- 中巴地球资源(CBERS)卫星系列介绍
- RESTful 接口设计规范
- MySQL int(M)数值类型中M值的意义
- 计算机笔记检讨,没做笔记检讨书
- 11_传智播客iOS视频教程_NS前缀和@符号
- MAC: docker compose mount permission denied 挂载失败
- RSF 分布式服务框架设计
- OO第四单元作业小结
热门文章
- 磕磕碰碰3个月,作为一名程序媛我的找工作经历,终于进了字节!!!
- Capstone CS5216方案设计|DP转HDMI1080P转接线设计|CS5216设计电路图
- html背景透明图片不透明,css中背景透明的图片不透明怎么解决
- Unity 点击UI(按钮)与点击屏幕冲突
- 值得收藏的一些HTML、JavaScript、ASP代码
- Out of memory: Kill process 内存不足
- 『创意欣赏』60款惊艳的 iOS App 图标设计《第四季》
- 安卓必备工具集-常用APK
- 举个例子讲下transformer的输入输出细节及其他
- 2021抖音五一数据报告