原创C语言高级用法-学习笔记

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

#是将其后的变量直接转换为字符串

void WriteLog(arg)

{

printf("%s=%d",#arg,arg)

}

1.##的作用

##的作用是连接两个变量

#define combine_converse_str(x,y) x##y

int Err;

int Num;

printf("%s",combine_converse_str(Err,Num));

结果为:ErrNum

再如:

int a=1;

int b=2;

int ab=3;

printf("%d",a##b);

结果为: 3

后面那句相当于printf("%d",ab);

2.do{ }while(0)作用

1,空的宏定义避免warning:

#define foo() do{}while(0)

2,存在一个独立的block,可以用来进行变量定义,进行比较复杂的实现。

3,用在宏定义上并且当宏定义需要定义成多条语句的组合时,可以保证这几条语句是一个整体的,并且可以消除使用这个宏定义后添加";"所带来的报错,例如:

#define aaa(x,y) \

do{ \

int a=0; \

int b=0; \

函数1(x); \

函数2(y); \

}while(0)

调用aaa(x,y); 时不会报错并且如果使用:

if (m)

aaa(1,2);

else

aaa(3,4);

时运行也不会使某些语句没有被运行到。

3.数组名的使用

A.数组名作为函数参数:数组名用在某个函数A的参数中时,处于函数传递效率原因,会被强制转换成了指针,此后在函数A内就完全是一个值等于对应数组首地址的指针变量,可自加自减等

注意!只有在作为函数参数的情况下才会将数组名强制转换成指针,其他的都不会转换。

另:数组名作为函数参数传递时,函数声明的写法有多种

int aaa(char x[])

int aaa(char x[1])

int aaa(char x[100])

int aaa(char *x)

作为函数参数时的参数声明也和普通的数组定义一样要合法,比如不能 int aaa(char x[0]),因为定义一个数组也不能用 char x[0]来定义,编译器在检查参数的声明合法后,如果发现参数是数组,就会强制转换成指针,所以int aaa(char x[1])和int aaa(char x[100])的结果是一样的。

B.数组名用在sizeof上:结果返回的是整个数组所占空间的大小,而不是一个指针的长度

C.数组名与&和*:a与&a与&a[0]的值都相等,a是数组名,&a是整个数组地址,&a[0]是数组首元素的地址,他们都相等

int a[5]={1,2,3,4,5};

printf("a=%x\n",a);

printf("&a=%x\n",&a);

printf("*&a=%x\n",*&a);

printf("&a[0]=%x\n",&a[0]);

printf("*&a[0]=%x\n",*&a[0]);

printf("*(&a[0])=%x\n",*(&a[0]));

printf("*((int *)(&a))=%x\n",*((int *)(&a)));

printf("*(*(&a))=%x\n",*(*(&a)));

结果:

a=12ff34

&a=12ff34

*&a=12ff34 ---*与&消掉,*&a=a=0x12ff34

&a[0]=12ff34

*&a[0]=1 ---*与&消掉,*&a[0]=a[0]=1

*(&a[0])=1 ---*与&消掉,*(&a[0])=*&a[0]=a[0]=1

*((int *)(&a))=1 ---*与&之间有个强制类型转换(int *),无法直接消掉,所以按照括号次序来运算(int *)(&a)=0x12ff34, *((int *)(&a))=*(0x12ff34)=1 *(*(&a))=1 ---*与&消掉,*(*(&a))=*a=1

D.指针数组:

定义:基类型*数组名[]

使用:像普通的数组一样使用,数组名代表首地址,数组名[0]表示第一个元素的内容,以此类推。

常见的是字符串数组,例如:

char *Names[]=

{

Bill,

Sam,

Jim

};

实际内存中保存的就是

即首地址0x12ff0c{0x00423018,0x0042f2f4,0042201c},其中0x00423018地址所保存的就是”Bill”,所以数组名Name=0x12ff0c, &Name=0x12ff0c,*Name=0x00423018,**Name=0x42

printf("Name=%x\n",Name);

printf("&Name=%x\n",&Name);

printf("*&Name=%x\n",*&Name);

printf("&Name[0]=%x\n",&Name[0]);

printf("*Name=%x\n",*Name);

printf("**Name=%x\n",**Name);

printf("Name[0]=%x\n",Name[0]);

printf("*Name[0]=%x\n",*Name[0]);

printf("*&Name[0]=%x\n",*&Name[0]);

printf("*(&Name[0])=%x\n",*(&Name[0]));

printf("(*((int *)(&Name)))=%x\n",(*((int *)(&Name))));

printf("(*(*(&Name)))=%x\n",(*(*(&Name))));

结果是

Name=&Name=*&Name=&Name[0]=0x12ff0c

*Name=Name[0]=*&Name[0]=*(&Name[0])=(*((int

*)(&Name)))=(*(*(&Name)))=0x00423018

**Name=*Name[0]=0x42

注意!指针是一级,数组是又一级,所以指针数组是二级指针,定义对应的指针变量要用二级指针,比如 int **p=Name; 不能直接用int *p=Name

4.常量的定义和指针常量的定义及使用:

1.常量的定义:

相关文档
最新文档