原创C语言高级用法-学习笔记
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 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.常量的定义: