void不能定义变量
- 示例:
1. int main() 2. { 3. void a; 4. return 0; 5. } 6. 在vs2013和Centos 7,gcc 4.8.5下都不能编译通过
- 解释:
定义变量的本质:开辟空间
void作为空类型,理论上是不应该开辟空间的,即使开了空间,也仅仅作为一个占位符看待
所以无法作为正常变量使用,故不能定义变量
void修饰函数返回值和参数
void用来作为函数返回值
void show() { printf("no return value!\n"); } int main() { show(); return 0; } //如果自定义函数,或者库函数不需要返回值,那么就可以写成void
注:不能不写,否则自定义函数的默认返回值是int(不写也会引起误会)
结论:void作为函数返回值,代表不需要
用来作为"占位符",告知编译器和阅读源代码的人
void 作为函数参数
int test1() //函数默认不需要参数 { return 1; } int test2(void) //明确函数不需要参数 { return 1; } int main() { printf("%d\n", test1(10)); //依旧传入参数,编译器不会告警或者报错 printf("%d\n", test2(10)); //依旧传入参数,编译器会告警(vs)或者报错(gcc) return 0; }
结论:如果一个函数没有参数,将参数列表设置成void
可以将错误明确提前发现同时可以告知阅读你代码的人
void *指针
void*能否定义变量?
int main() { void *p = NULL; //可以 return 0; }
- 解释:
为void*是指针,而只要是指针空间大小就能明确出来
void* 接受任意指针类型
int main() { void *p = NULL; int *x = NULL; double *y = NULL; p = x; //虽然类型不同,但是编译器并不报错 p = y; //同上 return 0; }
结论:void*一般是用来接受任意指针类型的(对于不知道类型的传址用来设计通用接口)
- 示例:
void * memset ( void * ptr, int value, size_t num );//memset库函数
int compare (const void * a, const void * b);//qsort库函数的compare函数设计
void * 定义的指针变量运算操作
结论:对于不同编译器,看待void空间大小不同,所以能否运算的结果不同
int main() { void *p = NULL; p++; p += 1; return 0; }
现象:在vs中报错 ,在gcc能通过
关键字-return
int test() { int a = 10; return a; //a是函数定义的变量,具有临时性,临时变量在函数退出的时候被释放 } int main() { int a = test(); printf("%d\n", a); return 0; }
- 返回值临时变量的本质:
对于一般内置类型,寄存器eax可以充当返回值的临时空间(存储返回值)
注意:当不接受返回值时,返回值依旧会传给寄存器eax
返回值在函数创建和销毁中具体过程:C语言内功的修炼--函数栈帧创建和销毁
关键字-const
const 修饰变量
int main() { const int i = 10; i = 20; //报错,代表变量i不可以直接被修改 return 0; }
注意:是不能直接修改,但可以通过指针来修改
- 示例:
int main() { const int i = 10; int *p = (int*)&i; printf("before: %d\n", i); *p = 20; printf("after: %d\n", i); return 0; }
意义:告诉编译器(便于直接检查出来),告诉程序员不要修改
注意:const定义的变量是常变量,本质上还是变量,一般无法作为数组定义的一部分
int main() { const int n = 100; int arr[n]; //一般编译器会报错 return 0; }
注意:const只能在定义的时候直接初始化,不能二次赋值
解释:const定义时如果没有赋值,但是会随机默认化(相当于初始化赋值了)
二次赋值是删去原值再修改,编译器会报错
const char * \char const *\ char * const 三者的区别
- const char *ptr等价于char const *ptr
const都在*左边,const修饰*,表示*ptr不能直接修改
即不能直接改变指针指向的内容,但可以直接改变指针指向
- char *const ptr
const在*右边,const修饰ptr表示不能直接改变指针指向,但可以直接改变指针指向的内容