1.在C语言中,const修饰的变量,表示只读变量,仍为变量,只是属性为只读。定义时必须初始化。所以不能用在初始化数组个数和case语句后面,因为它们要求为常量,常量表达式;但在C++程序中则可以,C++中扩展了const的含义。
在1.cpp中程序编译正确。
void main(void)
{
const int n=20;
int a[n];
int i=0;
switch (i)
{
case n:break;
default:
break;
}
while (1);
}
而改为1.c重新编译
输出结果如下:
2.const修饰的只读变量在编译时确定其值,有特定的数据类型;而#define宏定义,define不是关键字,在预编译时进行替换,没有类型。编译器不为普通const只读变量分配内存空间,将它们保存在符号表中,使其成为一个编译期间的值,没有存储与读内存的操作,效率高。(?)
#define M 3
const int N = 5; //此时并未把N放入内存中
int i = N; //此时为N分配内存,以后不再分配
int I = M; //预编译期间进行宏替换,分配内存
int j = N; //没有内存分配
int J = M; //再进行宏替换,又一次分配内存
所以尽量用const只读变量吗?
3.const修饰指针时,可以像编译器解析一样,先忽略类型名,然后再看const离谁近就修饰谁。
eg:
const int *p;//忽略int,const修饰*p,p为指针,*p为指针指向的对象,不可变。
Int * const p;//忽略int,const修饰p,p不可变,p指向的对象可变。
4.void *可以指向任何类型的指针,任何类型的指针都可以直接赋值给它,但void *不能直接赋值给其它类型的指针,必须经过强制类型转换。
eg:
void * p1;//定义指针时要初始化NULL
int * p2;
p1 = p2;//没有问题,可以把任何类型指针赋值给空指针
p2 = p1;//出错,没有强制类型转换时不能把空指针直接赋值给其它类型指针
5.return语句不可返回指向“栈内存”的指针,因为该内存在函数体结束时被自动销毁。
eg:
char * Func(void)
{
char str[6];
int i=0;
for(i;i<5;i++)
{
str = i+1+0x30;
}
str[5]=0;
printf("%s\n",str);//输出12345
return str;//str属于局部变量,位于栈内存中,在func函数结束时被释放,所以返回str将有问题。
}
在主函数中调用printf("%s",Func());输出结果如下所示:
7.平时我们要求函数的参数尽量不多于4个,参数太多了,效率会降低(与具体的CPU有关,ARM就对超过4个参数的处理有讲究)。参数太多,可以考虑使用结构体。
8.volatile修饰的变量,表示编译器对访问该变量的代码不再进行优化。定义一个变量,如果用该变量去初始化其他变量,在初始化语句中,只要该变量不作为左值,则编译器会优化该代码,不会生成汇编代码重新从内存中取该变量的值。相当于只取一次,可以用多次,提高效率。如果使用volatile修饰,告诉编译器不用优化该代码,每次都到内存中取值。
Eg:
int i = 10; volatile int i = 10;
int j = i; int j = i;
int k = i; int k = i;
文章评论(0条评论)
登录后参与讨论