分享

C语言

 豫龙晏子 2017-02-10

1、c语言中定义一个字符串:

char a[6]={'l','i','n','u','x','\0'}; '\0'的字符编码为0就是NULL;也就是说内存中遇到0,翻译成字符是就是'\0',或这是NULL;

char a[6]='linux';

char *p='linux';

2、sizeof(a)=6是运算符,其意思是所占空间大小,包括字符串后面的‘\0',strlen(a)=5是一个函数,其意思是字符串的长度。strlen( p);其中p只有是字符指针变量才有意义, 它的形参是数组变量是没有意义的,因为strlen是根据什么时候遇到 '\0',才结束测试字符串的长度,就算数组不初始化也是有长度的。

char *p='linux'; sizeof(p)永远等于4,因为p是指针变量,存的是地址。所以总结:sizeof()是拿来测数组的大小,strlen()是拿来测试字符串的长度。

3、结构体用 . 或者是 ->访问内部变量,其实质是用的指针访问。如

struct student

{

int a;

double b;

char c;

}s1;

则s1.a =12;实质就是int *p=(int *) &s1;*p=12 首先a是int 型,所以是强制类型 int * ,其次是就是算地址,然后强制类型,地址应该是int 型然后加减,不然的话,系统

s1.b=12.2;实质就是double *p= (double *) ((int)&s1+4),*p=12.2; 不知道是以int 型加减还是以float型加减,还是以char型加减,所以 应当 (int)&s1; 而且因为地址是

s1.c=c;实质就是 char *p=(char *) ((int)&s1+12); *p=c; 4字节的,所以必须是int型。

C语言----数组&字符串&结构体&共用体&枚举

加群466572167(群内有各类型学习资料)

4、对齐方式:

(1)猜测如果是32位系统,那么编译器默认是4字节对齐,64位系统,那么编译器默认是8字节对齐,因为32位或64位一次性访问效率是最高的。

(2)<1>结构体首地址对齐(编译器自身帮我们保证,会给它分配一个对齐的地址,因为结构体自身已经对齐了,那么第一个变量也就自然对齐,所以我们才可以想象成第一个变量从0地址存放);

<2>结构体内部的各个变量要对齐。

<3>整个结构体要对齐,因为定义结构体变量s1时,再定义变量s2时,如果s1没有对齐,就坑了s2,所以也要保证整个结构体对齐。

无论是按照几字节对齐,我们都可以联想到内存实际的安排。1字节对齐那么不管int float double 类型,在每4个格子的内存挨着存放。2字节对齐,也是一样的

想法,举一个列子,如果第一个变量是char 型,第二个变量是int型,那么0地址存放char型,1地址空着,2地址存放int型地址部分,3地址存放int型地址部分,然后

上排最右4、5地址存放int型高址部分。4字节对齐,如果第一个变量是char型,第二个变量是int型,那么0地址存放char型,1,2,3地址空着,从4地址开始存放int,

最后给变量分配完内存空间后,必须要保证整个结构体对齐,下一个结构体的存放起始地址是n字节对齐整数倍,如是4字节对齐,那么最后short算成4字节 以保证整个结构体对齐。

整个结构体对齐,如2字节对齐(2的整数倍),只要是0、2、4地址就行了,如果是4字节对齐(4的整数倍),就必须是0、4地址。8字节对齐(8的整数倍)

(3)猜测4字节/8字节其实是针对int型/double型的,比如0地址是char型,那么4字节对齐,int型、float型就必须从4地址开始存放,那么8字节对齐,int型就必须从4地址存放,double型就必须从8地址开始存放.小于几字节对齐的那些,如char型和short型只要能按照规则存放就行了。

(4)对齐命令:<1>需要#prgama pack(n)开头,以#pragma pack()结尾,定义一个区间,这个区间内的对齐参数就是n。(不建议使用) 加群466572167(群内有各类型学习资料)

如:s1占5个字节,s2占8字节(默认)

#pragma pack(1)

struct stu1

{

(结构体本身以及变量) 对齐规则:2字节对齐(2的整数倍),只要是0、2、4地址就行了,

4字节对齐(4的整数倍),就必须是0、4地址,

8字节对齐(8的整数倍),就必须是0、8、16

char c;

int a;

//short d;

}s1;

struct stu2 {

char c;

int a;

//short d;

}s2;

<2>gcc推荐的对齐指令__attribute__((packed)) __attribute__((aligned(n))),在VC中就不行,没有定义这个命令

(1)__attribute__((packed))使用时直接放在要进行内存对齐的类型定义的后面,然后它起作用的范围只有加了这个东西的这一个类型。packed的作用就是取消对齐访问。

(2)__attribute__((aligned(n)))使用时直接放在要进行内存对齐的类型定义的后面,然后它起作用的范围只有加了这个东西的这一个类型。它的作用是让整个结构体变量 整体进行n字节对齐(注意是结构体变量整体n字节对齐,而不是结构体内各元素也要n字节对齐,内部元素按照默认对齐方式)

5、枚举类型(int型): 这样写默认从第一个常量开始是0,1,2,3,4.........

也可以自己赋值,但是每一个值是不一样的,否则逻辑上出错。

typedef enum workday

{

MON, // MON = 1;

TUE,

WEN,

THU,

FRI,

}DAY;

typedef enum weekend

{

SAT,

SUN,

}DAY;

*/

/ /错误2,枚举成员重名,编译时报错:redeclaration of enumerator ‘MON’

typedef enum workday

{

MON, // MON = 1;

TUE,

WEN,

THU,

FRI,

}workday;

typedef enum weekend

{

MON,

SAT,

SUN,

}weekend;

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多