C知识点总结结构体指针使用

  • 格式:doc
  • 大小:504.50 KB
  • 文档页数:4

下载文档原格式

  / 4
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

位操作:熟悉& | ^ << >>操作。应聘嵌入式C开发的岗位会考这方面的知识。见实验5。

结构体共用体

如前面讲的,作为函数参数和返回值,结构体是值传递。结构体变量之间可以直接赋值,结构体在初始化时才能整体赋值。

C99里新的结构体初始化方法。初始化结构体的指定成员变量。见《C primer plus》P382 struct book{char a; int b; double c }; struct book surprise ={ .b=3 };即初始化指定的成员变量b,其他成员变量的值赋值为0。在内核驱动代码中会经常见到。

指向结构体的指针及使用

struct node { int data; struct node *next; } node1;

struct node *point=&node1;

内存模型

高地址Array [ point ] ----- > node1

此时,point指向node1。即*point和node1对应的是同一块内存。

(*point).data等价于node1.data对应的是同一块内存。

(*point).next等价于node1.next对应的是同一块内存。即黄色背景的内存。

point->next

为什么这段代码行得通:

int offset= &( ( (struct book*) 0 )->b); //获得成员变量b在结构体的偏移量。

等价于:struct book *ptr=NULL; int offset= & ( ptr->b) ; // &(*ptr).b ;

编译器维护关于每个结构类型的信息,指示每个字段的字节偏移。它以这些偏移作为存储器引用指令中的移位,从而产生对结构元素的引用的代码。结构体的各个字段的选取完全是在编译时处理的。参考《深入理解》P166页中的一个例子。

程序对内存的访问,都是先生成该内存的地址,再访问该内存。

结构体对齐,及填充

结构体的对齐与填充

C语言标准未严格规定该如何对齐,不同系统的对齐策略略有不同。

参考《深入理解》P170数据对齐。

linux策略:linux/IA32 (Intel Architecture 32)下,基本类型按其占用字节大小对齐。(即该类型变量的首地址能被sizeof(类型)整除,基本类型是指泛整形和浮点类型)。

结构体按其最大成员变量的对齐规则对齐。若结构体按n个字节对齐,那么结构体的大小也要能被n整除。

结构体内的成员按上图的方式对齐。

struct S{ int a; char b; }; 该结构体按其最大成员int的对齐规则对齐。

结构体struct S 按4个字节对齐,即它的首地址和大小必须都能被4整除。

因为有对齐的要求就出现了内存填充(空着若干个字节,不使用)。

A

B

C

D

E

3.42

如何尽量避免填充带来的分析影响:结构体定义按成员对齐规则从大到小书写,这样填充只会在尾部填充。当然,逻辑关系的考虑也很重要。

位域:整形类型(一般用unsigned int)

不能对结构体里的位字段取地址。

判断一个char ch=0x12字节内位序

共用体:首地址对齐。

判断系统是否为大端

指向函数的指针及库函数的使用:exit atexit

《C语言495个问题》1.36 4.12

枚举类型的使用:对一类宏的整体定义。

struct week{Sunday, };

使用库函数进行文件操作:缓冲区设置函数,文件操作库函数的使用。

学习对这些函数的使用时,请同学们参考《apue》第五章,这里会告诉大家函数的优点、缺点。比谭浩强的书描述要准确。

文件流:是全缓冲的。可以使用fseek进行位置移动。

标准输入输出流:是行缓冲的。不可以使用fseek等移动读写位置

标准错误输出流:是不缓冲的。不可以使用fseek等移动读写位置。P110

标准库函数区分文本文件和二进制文件。但在linux系统里并不对这两种文件区分,所以,在linux环境下,指定字符b作为type的一部分实际上不起作用。P113 const、volatile等限定符

restrict:是c99才支持的,形参指针用restrict修饰的函数,告诉编译器在该函数内只通过这一个指针引用他所指的内存。这样,编译器就可以对该指针的操作进行代码优化。编

译时需要在gcc后面加-std=c99

volatile:用该符号限定变量,告诉编译器每次使用到该变量值的时候,都要从存储它的位置重新取它的值。对于那些值容易变化的变量,需要加这个限定符。通常用在多线程编程中,嵌入式的硬件寄存器。

restrict和volatile都是为了方便编译器进行代码优化。

volatile int i=3; movl $3 -4(%ebp) ;

int b=i; movl -4(%ebp) %eax; movl %eax -8(%ebp);

int c=i; movl -4(%ebp) %eax ; movl %eax -12(%ebp)