一、goto关键字
-
#include <stdio.h> int main() { int a = 10; start://冒号记得要加 printf("%d\n", a); if (a > 0) { printf("hello\n"); } goto start; return 0; }
goto关键字使用注意事项:goto语句只能用于在当前函数内部进行跳转,不能跨函数或跳出函数
二、void关键字
- void本身就被解释为空类型,强制不允许定义变量,因为大小不明确
- 不允许强制类型转化 int a = (void)10写法错误
- C语言中,函数可以不带返回类型,此时默认返回值是int,比如定义函数:add()此函数没带返回类型,默认返回int,并且默认函数不需要参数
- add(void)明确函数不需要参数,如果一个函数没有参数,将参数列表设置成void,是一个不错的习惯,因为可以将错误明确提前发现
- void修饰函数返回值时,①:占位符,让用户明确不需要返回值 ②:告知编译器此返回值无法接受
void*
- void* 可以定义变量,因为是指针,类型明确,大小为4/8个字节
- void* 能被任何类型的指针接收
- void* 能接收任意类型的指针(常用)
- void* 的指针不能解引用,不能加减
- 在vs中sizeof(void)为0,而在Linux中sizeof(void)为1可以解引用和加减运算(了解)
三、return关键字
了解return之前,我们要先了解一些概念
- C语言没有字符串类型,有字符串
- 计算机所谓的删除是否真的将数据全部清0\1?计算机不会真的清空数据,只要设置该数据无效即可(无效:数据可被覆盖)
- 栈帧:是指在程序执行过程中,每个函数调用前预先在栈上分配的一块内存区域
- 函数调用形成栈帧,函数返回释放栈帧
- 调用show函数形成栈帧,返回释放栈帧,只是设置数据为无效,并不会清除数据(数据还在),但紧接着调用printf函数时,形成栈帧,将原来的栈帧覆盖(原数据不在了,被覆盖)
- 函数的返回值先临时储存在寄存器当中,再返回给函数调用方,通过查看汇编可以看到,对于一般内置类型,寄存器eax可以充当返回值的临时空间
- 为什么临时变量具有临时性?因为栈帧结构在函数调用完毕后需要被释放,临时变量在函数栈帧中开辟内存
四、const
- const修饰的变量不可直接被修改,可通过指针间接修改(int a = 10;int* p = &a;*p = 20)
- const可放在类型前,也可放在类型后,建议放类型前
- const int a = 10;a并不是真正的常量,因为a可以被间接修该,所以int arr[a], case a都错误
const修饰的变量并非不可被修改,那const修饰变量,意义何在?
- ①:让编译器直接进行修改检查,若被修改直接警告或报错
- ②:告诉其他程序员这个变量不要改,也属于一种自描述
- char* p = "hello bit"这才是真正意义上的不可被修改(关于这块的处理需了解操作系统)
const修饰数组
代表数组中的每个元素都不可被修改
const修饰指针
- 指针:就是一个地址
- 指针变量:一个变量,用来保存地址(注意区分两者的差别)
- 为什么要有指针?提高CPU内存寻址的效率
- 地址需要开辟空间存储吗?不需要,内存中每个地方的地址是由计算机规定好的
- 地址为只读,不能随便改
- 在c中,任何变量&,全都是从最低地址开始的
左值和右值的区别
- int x x = 100 x的空间(把100放到x的空间里面),变量的属性,左值
- int y = x x的内容,数据的属性(把x的值赋给y),右值
对指针解引用,代表指针所指向的目标
int a = 10;
const int* p = &a; int* q = p;(警告)
int* p = &a; const int* q = p; (无警告)
经验:如果把一个类型限定并不严格的变量,赋给一个类型限定非常严格的变量,编译器不会报错;如果把一个类型限定非常严格的变量,赋给一个类型限定并不严格的变量,编译器会报错
const修饰函数
- 在c中,任何函数传参都一定要形成临时变量,包括指针变量
const修饰函数参数:该参数不可被修改,只读
const修饰函数返回值:const int* test()告诉编译器,告诉函数调用者不要试图通过指针修改函数返回值所指向的内容
个人主页:是冬至呀-CSDN博客