九:goto关键字 第一: goto基本控制逻辑或者基本语法如下 int main() { int i = 0; START: printf('[%d]goto running ... \n', i); Sleep(1000); ++i; if (i < 10){ goto START; } printf('goto end ... \n'); return 0; } 十:void关键字 第一: void是不能用来定义变量的。因为定义变量的本质就是开辟内存空间,而void作为空类型是不应该开辟空间的,即使开辟了空间,也仅仅作为一个占位符来看待,所以这种行为直接就会被编译器禁止 第二: 首先说明一点,在C语言中函数是可以不带返回值的,返回类型为整型 的确在有些场景中我们是不需要函数的返回值的,但如果采用上面的那种方式书写,很容易产生阅读上的歧义,因此如果函数不想让其返回,可以用void,这里一定要将其理解为一种占位符,它是告知用户和编译器的 第二: 在如下情形中,编译器是不会报错的,因此会有很大的安全隐患 而如果限制void后,编译器将会报警。因此void可以充当函数的形参列表,用于告知编译器和用户该函数不需要传入参数 第四: void的确不可以定义变量,但是void*可以,因为指针变量的大小是明确的(Windows32位下为4个字节大小) void* p=nullptr; 第五: void可以被任何类型的指针接受,void也可以接受任意指针类型 int main() { void p = NULL; int x = NULL; double y = NULL; p = x;//void接受int p = y;//void接受double* }
第六: 我们知道,普通类型的指针可以进行位运算 int* p=NULL; p++; p--; 而对于void*呢?要视平台而定,一般VS下不可以,Linux下可以(Linux认为void是1) 十一:return关键字 第一:return不可以返回指向“栈内存”的指针,因为在函数体结束时会被自动销毁 因此下面的语句会出现乱码 char show() { char str[] = 'hello world'; return str; } int main() { char s = show(); printf('%s\n', s); return 0; } 第二: 函数的返回值,通过寄存器的方式,返回给函数的调用方(注意区别上面,上面不能那样做,因为那是指向栈的指针) int GetData() { int x = 0x11223344; printf('running\n'); return x; } int main() { int y = GetData(); printf('return value:%x\n', y); return 0; } return x对应的汇编代码为: 十二:const关键字 第一: const修饰的变量不可以直接被修改 const int a=10; a=20;//错误 但间接可以修改 int main() { const int a = 10; int p = &a; printf('change before:%d\n', a); p = 20; printf('change after:%d\n', a); return 0; } 那么既然这样其意义何在呢?其实const修饰变量主要有下面两个目的
真正意义上的不可修改如C语言中的常量字符串 int main() { char str = 'hello world\n';//常量字符串 str ='E'; return 0; } 第二: const int i 和int const i是等价的 第三: const修饰的变量同样不能作为数组定义的一部分(标准C不可以,但是在Linux可以) int main() { const int n = 100; int arr[n];//错误 return 0; } 第四: const在定义时必须初始化 第五: 建立只读数组可以这样写 int const a[5]={1,2,3,4,5}; 或 const int a[5]={1,2,3,4,5}; 第六 :const放在谁后面就修饰谁,因此它与指针的关系如下 ①:const int i 与int const i等价 其中i是指针,const修饰了int,表示指针可以变化,但是指针指向内容不能被修改 ②:int* const i const修饰的是指针,所以指针不可变,但是指向的内容可变 ③:const int* const i=&a 表示指针不可以变,指向的内容也不可以变 第七: const 也可以用来修饰函数参数,表明不可更改 void show(const int p)//防止指针指向内容被修改 { printf('value:%d\n', p); p = 20;//非法操作 } int main() { int a = 10; int* p = &a; show(p); } 十三:volatile关键字 有关volatile关键字的作用在下面这篇文章中有详细介绍,请移步
volatile关键字的作用:volatile将保持内存的可见性,一个变量一旦被volatile修饰,那么系统总是会从内存中读取数据,而不是从寄存器 需要注意const和volatile的区别,两者并不矛盾
十四:extern关键字 extern关键字这里就多说了,非常简单 十五:struct关键字 第一: struct基本介绍 定义 初始化(不能初始化后整体赋值) 成员访问 结构体传参 第二: 在Linux中空结构体的大小为0 第三: 柔性数组 我们知道C语言中是不能有这样的操作的,就是用变量对数组进行初始化 int main() { int i=0; scanf('%d',&i); int arr[i]; } 在C语言中如果要完成动态数组,可以借助柔性数组。使用柔性数组时,我们采用结构体的方式,将一个数组作为结构体成员放置于其中,但注意该数组不初始化,什么都不写 在上述结构体中,有两个结构体变量,数组似乎不占空间,但其实不然。实则,该结构体将其所占空间划分为两部分,一部分就是那个整形,一部分用于动态开辟,以此满足数组的动态变化 既然是柔性,那就可以修改,使用realloc修改 十六:Union关键字 第一: Union是什么 联合也是一种特殊的自定义类型 这种类型定义的变量也包含一系列的成员,特征是这些成员公用同一块空间,联合体内所有成员的起始地址都是一样的,每个成员都认为它是联合体的第一个成员 第二: 根据内存地址分布,如下,b永远定义在相对于a的低地址处 union Un { int a; int b; }; 根据这一性质我们可以利用联合体来判断机器是大端机还是小端机,如下 union Un { int a; char b; }; int main() { union Un u; u.a = 1; if (u.b == 1){ printf('小端机\n'); } else { printf('大端机\n'); } return 0; } 这是因为 十七:enum关键字 enum用于枚举一堆常量,就像Excel中的数据有效性,它规定了数据的取值类型,比如说男性它只有男或女 定义 enum color是枚举类型,括号中的内容是枚举类型的可能取值,也叫做枚举常量。这些可能取值实际上是有值的,默认是从0开始的 当然是可以修改的 枚举的这样的写法其实和宏的写法在代码的逻辑上是相似的 十八:typedef关键字 第一: typedef的作用就是为类型重新命名 typedef unsigned int uint; int main() { uint a = 10; return 0; } typedef 经常会在结构体重命名里 typedef struct stu { int a; int b; }Student; int main() { Student student1; } 第二: 大家一定要对typedef理解到位,如下 int main() { int* a, b; //a是指针类型 //b是整形 } typedef从某种方面可以理解一种全新的类型,因此下面的*就不存在和谁结合的问题了 typedef int intp; int main() { int_p a, b; //a是指针类型 //b也是指针类型 } 而对于#define而言它就是一种文本替换了,因此 #define intp int int main() { int_p a, b; //a是指针类型 //b是整形 } 第三:使用typedef定义后的新类型,不能配合其他关键字使用 #define INTDE int typedef int INTTY; int main() { unsigned INTDE a;//正确 unsigned INTTY b;//错误 } 总结 (1)关键字分类 数据类型关键字 :
控制语句关键字 : 1:循环控制
2:条件语句
3:开关语句
4:返回语句
存储类型关键字 :
这里需要补充一点:使用typedef时不能同时出现多个存储关键字 typedef static int//错误 typedef register int//错误 其他关键字 :
|
|
来自: 启云_9137 > 《计算机及软件应用》