当前位置: 首页 > news >正文

C语言专题——关键字详解

C语言专题——关键字详解

  • 前言
    • 为什么这篇文章值得你点赞收藏?
    • 适合谁读?
    • 互动时间
  • 关键字汇总
    • 数据类型关键字
      • 基本数据类型
      • 类型修饰符
    • 流程控制关键字
      • 条件语句
      • 循环语句
      • 跳转语句
      • 其他关键字
  • 关键字用法避坑指南
    • for循环
      • 基本用法和执行顺序
      • 循环变量
      • 注意事项
    • sizeof关键字
      • 基本用法
      • 示例代码
      • 关键特性
      • 常见应用场景
      • 注意事项
    • switch语句
      • 基本语法
      • 关键特性
      • 示例代码
        • 基本用法(带break)
        • fall-through行为(省略break)
        • 使用enum类型
      • 注意事项
      • 与if-else的对比
      • 常见应用场景
    • break和continue的区别
      • 语法与基本作用
      • 循环中的行为差异
      • 示例对比
      • 常见应用场景
      • 注意事项
    • const int * p 和 int * const p区别
    • 柔性数组
    • void类型的指针
      • 核心特性
      • 常见用法
        • 作为函数参数(泛型编程)
        • 作为函数返回值
        • 实现通用数据结构
      • 指针转换规则
        • 隐式转换
        • 显式强制转换
      • 使用限制
        • 不能直接解引用
        • 不能进行指针算术运算
      • 类型安全问题
      • 典型应用场景
    • union关键字和大小端
      • union关键字
      • 大小端字节序(Endianness)
      • 使用union检测大小端
      • union与大小端的应用场景
    • 一些重要的编程建议

前言

学C语言的宝子们看过来!这篇耗时3天整理的「C语言关键字全攻略」终于完工啦~从32个关键字的分类解析到实战避坑指南,手把手带你吃透C语言的核心语法,收藏这篇=拥有一本「C语言关键字字典」,从此编程再也不怕语法坑!

为什么这篇文章值得你点赞收藏?

  1. 32个关键字系统分类
    把C语言32个关键字按数据类型、流程控制、存储类等维度拆解,每个关键字配示例代码,比教科书更易懂!比如static修饰变量和函数的不同作用域,volatile防止编译器优化的场景,一看就明白~

  2. 避坑指南直击痛点
    专门整理了for循环越界sizeof误用switch分支陷阱等高频错误,每个坑都带调试示例和解决方案。比如为什么void*指针不能直接解引用?const int*int* const到底怎么区分?这里全讲透!

  3. 进阶知识一网打尽
    除了基础关键字,还涵盖柔性数组、大小端检测、union与内存对齐等进阶内容。用union检测系统字节序的代码直接复制就能用,面试被问到时再也不慌~

适合谁读?

  • 刚入门C语言,被关键字搞到头晕的新手
  • 想系统梳理知识体系的编程学习者
  • 需要查缺补漏的开发人员

互动时间

如果你在学C语言时遇到过关键字相关的奇葩bug,或者想让我讲解某个语法点,可以在评论区留言~觉得文章有用的话,别忘了「点赞+收藏+关注」,后续会更新更多C语言进阶干货哦!

关键字汇总

C语言共有32个关键字,用法分类整理如下:

数据类型关键字

基本数据类型

  • int:声明整数类型变量,如int age = 25;
  • float:声明单精度浮点型变量,如float price = 9.99;
  • double:声明双精度浮点型变量,如double pi = 3.14159;
  • char:声明字符型变量,如char grade = 'A';
  • void:表示无类型,常用于函数返回值或指针,如void printHello();

类型修饰符

  • short:修饰整数,缩短其长度,如short int num = 100;

  • long:修饰整数或双精度浮点数,加长其长度,如long int distance = 1000000L;

  • signed:声明有符号数,如signed int balance = -500;

  • unsigned:声明无符号数,如unsigned int count = 1000;

  • const:声明只读变量,如const float PI = 3.14;

  • volatile:告诉编译器变量值可能意外改变,如volatile int sensorValue;定义变量的时候加上这个关键字,可以防止编译器优化。另外程序在读取这个变量的时候,即便上一次的读取值在cashe中,也必须从内存中重新读取。

  • auto:自动变量(默认),如auto int temp;等效于int temp;。在缺省情况下,编译器默认所有变量都是auto的,就当它不存在吧。

  • register建议编译器将变量存储在寄存器中,如register int counter;当然“建议”也只是“建议”而已,在代码编译中不一定能放进寄存器里面,毕竟寄存器数量有限,而且还有其他用途。如果一个变量需要快速访问,可以定义为此类型。

  • static

    • 修饰变量
      • 修饰全局变量,则作用域是从定义变量处开始,到文件结束处,其他文件无法使用此变量。即便在其他文件中extern此变量也无法使用,仅限本文件使用。
      • 修饰局部变量,在函数体内部定义,如函数内部定义static int count = 0; 它只能在函数体内使用,但延长了变量的生命周期,在退出函数之后此变量仍然存在。从生命周期上看,跟全局变量无异。
    • 修饰函数
      • 函数前加static,就是静态函数,使得函数的作用域仅限在本文件,其他文件无法调用此函数。这样的好处是不用担心与其他文件中的函数重名。
  • extern:声明外部变量,比如在一个源文件里面定义了变量 int sharedVar;,在另一个文件中需要使用此变量,就需要写extern int sharedVar;才可以使用此变量。

流程控制关键字

条件语句

  • if:条件判断,如if (score >= 60) { ... }
  • else:与if配合使用,如else { ...}
  • switch:多分支选择,如switch (day) { case 1: ...}
  • case:用于switch语句中,标记每个分支
  • defaultswitch语句中的默认分支

循环语句

  • for:固定次数循环,如for (int i=0; i<10; i++) { ... }
  • while:条件循环,如while (condition) { ... }
  • do:与while配合,至少执行一次,如do { ... } while (condition);
  • break:跳出循环或switch语句
  • continue:跳过本次循环剩余部分,继续下次循环

跳转语句

  • goto:无条件跳转,如goto found;
  • return:从函数返回值,如return result;

其他关键字

  • struct:定义结构体类型,如struct Point { int x, y; };
  • union:定义共用体类型,如union Data { int i; float f; };
  • enum:定义枚举类型,如enum Color { RED, GREEN, BLUE };
  • typedef:为类型定义别名,如typedef unsigned int uint32_t;
  • sizeof:计算数据类型或变量大小,如sizeof(int)

关键字用法避坑指南

for循环

基本用法和执行顺序

在for循环中,容易忽略一点,就是执行顺序。
for(代码1; 代码2;代码3)
{
  循环体;
}
程序执行到for循环这里,首先执行代码1,之后执行代码2,之后执行循环体,最后执行代码3,之后又执行代码2,执行循环体,再执行代码3,执行代码2……
例如下面的例子:

	int i = 0;for(printf("apple\n"); \printf("banana\n"); \printf("orange\n")){printf("Hello world\n");if(i == 1){break;}     i ++;   }

循环变量

在for循环之外定义的变量,可以在for循环里面定义同名变量用于控制循环次数。

int i = 50;
for(int i = 0; i < 5; i++)
{printf("In for circulation : i = %d\n", i);
}printf("out of for circulation : i = %d\n", i);   

在这里插入图片描述
循环变量的作用域只在循环体有效。

	for(int i = 0; i < 5; i++){        //循环体}i = 100; // 报错!没有定义此变量

注意事项

  • 除非必要,避免在循环体中直接修改循环变量。
  • 若需调整迭代逻辑,优先使用continue或break。
  • 数组越界访问。循环索引超出数组边界,导致未定义行为(如段错误、数据损坏)。

示例代码:

int arr[5];
for (int i = 0; i <= 5; i++) {  // 错误:i=5时越界arr[i] = i;  // 访问arr[5]超出合法范围(0~4)
}

正确做法:始终确保索引范围为0到数组长度-1。
使用sizeof计算数组长度:

for (int i = 0; i < sizeof(arr)/sizeof(arr[0]); i++) 
{// ...
}

sizeof关键字

sizeof是关键字,不是函数!

sizeof 是一个编译时一元运算符,其主要功能是计算数据类型或者变量在内存中所占的字节数。下面为你详细介绍它的用法、特点以及相关注意事项:

基本用法

sizeof 有两种使用形式:

  1. 计算数据类型的大小sizeof(类型名)
  2. 计算变量的大小sizeof(变量名) 或者 sizeof 变量名(后一种形式仅适用于变量)例如:
int i = 0;
int b = sizeof i;//b = 4
printf("b = %d\n", b);

示例代码

sizeof 运算符返回的类型是 size_t。下面先讲一下%zu格式说明符的作用:

  • %z是长度修饰符,它表明要输出的数值类型是size_t
  • u代表无符号十进制整数。

所以,%zu专门用于正确输出size_t类型的值,不管该值在当前系统中是32位还是64位。

#include <stdio.h>int main() {// 计算基本数据类型的大小printf("char: %zu 字节\n", sizeof(char));         // 通常输出1printf("int: %zu 字节\n", sizeof(int));           // 通常输出4printf("float: %zu 字节\n", sizeof(float));       // 通常输出4printf("double: %zu 字节\n", sizeof(double));     // 通常输出8// 计算变量的大小int num = 100;printf("num: %zu 字节\n", sizeof num);            // 可以省略括号printf("num: %zu 字节\n", sizeof(num));          // 与上一行等价// 计算数组的大小int arr[5];printf("arr: %zu 字节\n", sizeof(arr));           // 输出4*5,等于20printf("arr元素个数: %zu\n", sizeof(arr)/sizeof(arr[0])); // 输出5// 计算结构体的大小struct Point {int x;int y;};printf("struct Point: %zu 字节\n", sizeof(struct Point)); // 输出8(4+4)return 0;
}

关键特性

  1. 编译时求值sizeof 的计算过程是在编译阶段完成的,不会在程序运行时执行。因此,它可以用于定义数组大小,例如:int arr[sizeof(int)];(不过这种写法并不常见)。
	int arr0[sizeof(int) * 10] = {0};printf("sizeof(arr) = %zu\n",sizeof(arr0));//sizeof(arr) = 160
  1. 返回值类型sizeof 的返回值类型是 size_t,在打印时需要使用 %zu 格式说明符。
  2. 对指针的处理:若 p 是指针,sizeof(p) 返回的是指针本身的大小(在32位系统中通常是4字节,在64位系统中通常是8字节),而非指针所指向对象的大小。例如:
int *p = malloc(100 * sizeof(int));
printf("%zu\n", sizeof(p));  // 输出4(32位系统)
printf("%zu\n", sizeof(*p)); // 输出4(int的大小)
  1. 对数组的处理sizeof 作用于数组名时,返回的是整个数组的大小,而非指针的大小。但若数组作为参数传递给函数,数组名会退化为指针。例如:
void func(int arr[]) {printf("%zu\n", sizeof(arr));  // 输出4(32位系统),数组退化为指针
}
/*上面的函数等效于:
void func(int *arr)
{printf("%zu\n", sizeof(arr)); 
}
*/int main() {int arr[10];printf("%zu\n", sizeof(arr));  // 输出40(4*10)func(arr);return 0;
}
  1. 结构体的内存对齐:结构体的大小可能会大于其各成员大小之和,这是因为编译器为了提高内存访问效率,会进行内存对齐操作。例如:
struct Example {char c;     // 1字节int i;      // 4字节short s;    // 2字节
};
// 由于内存对齐,该结构体的大小通常为12字节,而非7字节

内存对齐的时候,以占用空间最大的成员变量为准,然后进行内存对齐操作。比如int类型占用空间最大,是4字节,所以就是4字节对齐。存放char只需要1字节,但后面是int,故空出3字节,再存放int类型,最后short类型原本2字节就可以,但要求4字节对齐,导致最后占用了12字节。

但是成员的顺序也会影响到内存对齐。比如:

struct Example {char c;     // 1字节short s;    // 2字节int i;      // 4字节
};
// 由于内存对齐,该结构体的大小通常为8字节,而非7字节

将成员的顺序改变之后,占用的内存就变成了8字节。

常见应用场景

  1. 动态内存分配:在使用 malloccalloc 等函数分配内存时,sizeof 能确保分配的内存大小与数据类型相匹配。例如:
int *arr = malloc(10 * sizeof(int));  // 分配10个int的空间
  1. 计算数组元素个数:通过 sizeof(arr)/sizeof(arr[0]) 可以计算出数组的元素个数。例如:
int arr[] = {1, 2, 3, 4, 5};
int count = sizeof(arr)/sizeof(arr[0]);  // count的值为5
  1. 平台无关性编程:使用 sizeof 可以编写不依赖于特定平台数据类型大小的代码,增强代码的可移植性。

注意事项

  1. 不要对函数调用使用 sizeofsizeof 不会执行函数,它只关心函数返回值的类型。例如:
int func() { return 10; }
printf("%zu\n", sizeof(func()));  // 输出4(int的大小),函数不会被调用
  1. void 类型使用 sizeof:例如,sizeof(void) 得到的结果是1。
printf("sizeof(void): %zu 字节\n", sizeof(void)); //输出1
  1. 对不完整类型使用 sizeof 是非法的:例如,声明但未定义的结构体不能使用 sizeof
typedef struct Point Point;  // 前置声明int main() {printf("%zu\n", sizeof(Point));  // 错误!未定义Pointreturn 0;
}// 即使在后面定义了结构体,这里的错误也不会被修正
struct Point { int x, y; };

switch语句

在C语言中,switch语句是一种多分支选择结构,用于基于某个表达式的值来执行不同的代码块。它提供了一种比嵌套if-else语句更清晰、更高效的方式来处理多种可能的情况。

基本语法

switch (expression) {case constant1:// 当expression等于constant1时执行的代码break;case constant2:// 当expression等于constant2时执行的代码break;...case constantN:// 当expression等于constantN时执行的代码break;default:// 当expression不匹配任何case时执行的代码break;
}

关键特性

  1. 表达式类型限制

    • expression必须是整数类型(如intcharenum)或可以隐式转换为整数类型的表达式。
    • 不支持浮点数或字符串作为表达式类型。
  2. case标签要求

    • 每个case标签后的值必须是常量表达式,如字面量或宏定义,不能是变量。
    • 同一个switch中,所有case标签的值必须唯一
  3. break语句的作用

    • 当执行到break时,会跳出整个switch语句。
    • 如果省略break,程序会继续执行后续case的代码(称为"fall-through"),直到遇到breakswitch结束。
  4. default分支

    • 可选的default分支会在所有case都不匹配时执行。
    • 通常放在switch的末尾,但位置不影响功能。

示例代码

基本用法(带break)
#include <stdio.h>int main() {int day = 3;switch (day) {case 1:printf("Monday\n");break;case 2:printf("Tuesday\n");break;case 3:printf("Wednesday\n");  // 匹配此分支,执行后跳出break;case 4:printf("Thursday\n");break;default:printf("Other day\n");}return 0;
}
fall-through行为(省略break)
int main() {int month = 2;switch (month) {case 1:case 3:case 5:case 7:case 8:case 10:case 12:printf("31 days\n");  // 1、3、5、7、8、10、12月共有此输出break;case 4:case 6:case 9:case 11:printf("30 days\n");  // 4、6、9、11月共有此输出break;case 2:printf("28 or 29 days\n");  // 2月特殊处理break;default:printf("Invalid month\n");}return 0;
}
使用enum类型
#include <stdio.h>enum Color { RED, GREEN, BLUE };int main() {enum Color c = GREEN;switch (c) {case RED:printf("Color is red\n");break;case GREEN:printf("Color is green\n");  // 匹配此分支break;case BLUE:printf("Color is blue\n");break;}return 0;
}

注意事项

  1. case标签不能重复

    switch (x) {case 1: ...case 1: ...  // 错误!重复的case值
    }
    
  2. 避免空case块

    switch (x) {case 1:  // 无代码,会fall-through到下一个casecase 2:printf("x is 1 or 2\n");break;
    }
    
  3. 表达式结果必须是整数类型

    float f = 1.5;
    switch (f) {  // 错误!不支持浮点数case 1.5: ...  // 错误!case值必须是整数常量
    }
    
  4. 嵌套switch
    可以在一个switch内部嵌套另一个switch,但要注意标签作用域:

    switch (x) {case 1:switch (y) {case 1: ...case 2: ...}break;case 2: ...
    }
    

与if-else的对比

  • switch优点
    • 代码更简洁,尤其在处理大量分支时。
    • 编译器可能会优化为跳转表(jump table),执行效率更高。
  • switch缺点
    • 只能基于整数表达式进行判断。
    • 每个case必须是常量值。

常见应用场景

  1. 菜单选择系统。
  2. 根据错误码执行不同处理。
  3. 状态机实现。

break和continue的区别

在C语言中,breakcontinue是用于控制循环流程的两个关键字,它们的主要区别在于对循环执行的影响不同。下面从语法、作用和示例三个方面详细说明:

语法与基本作用

关键字语法作用范围执行效果
breakbreak;只能用于forwhiledo-while循环或switch语句对于循环语句,程序跳出循环。 对于switch语句,程序跳出switch语句。
continuecontinue;只能用于forwhiledo-while循环跳过当前循环体中剩余的代码,直接进入下一次循环的条件判断(for循环还会执行更新表达式)。

循环中的行为差异

for (初始化; 条件; 更新) {if (条件A) break;     // 终止整个循环,不再执行更新和条件判断if (条件B) continue;  // 跳过剩余代码,执行更新 → 条件判断
}

示例对比

示例1:break的效果

for (int i = 0; i < 5; i++) {if (i == 3) break;  // 当i=3时终止循环printf("%d ", i);
}
// 输出:0 1 2

示例2:continue的效果

for (int i = 0; i < 5; i++) {if (i == 3) continue;  // 当i=3时跳过后续代码,进入下一次循环printf("%d ", i);
}
// 输出:0 1 2 4

常见应用场景

关键字典型应用场景
break- 在switch语句中跳出分支
- 提前终止循环(如找到目标值后)
- 避免无限循环
continue- 过滤某些不需要处理的情况(如跳过无效数据)
- 简化嵌套条件判断

注意事项

  1. 作用范围

    • breakcontinue只能影响当前所在的最内层循环。若要跳出多层循环,需使用goto
  2. do-while中的差异

    • continuedo-while中会直接跳到条件判断,而do-while的特点是至少执行一次循环体。

const int * p 和 int * const p区别

const int * p:p可变,p指向的对象不可变。
int const * p:p可变,p指向的对象不可变。
int * const p:p指向的对象可变,p不可变。
const int * const p:p和p指向的对象都不可变。

注意:记忆方法,将类型名int去掉,拿第一个来说,去掉之后是:const * p,const修饰的是*p,也就是p指向的对象,所以指向的对象不可变。

柔性数组

/*定义柔性数组*/
typedef struct st_type
{int i;      // 4字节int a[];
}type_a;int main()
{printf("sizeof(type_a) = %zu\n", sizeof(type_a));type_a *p = (type_a *)malloc(sizeof(type_a) + 10 * sizeof(int));for(int i = 0; i < 10; i++){p->a[i] = i;}for(int i = 0; i < 10; i++){printf("p->a[%d] = %d\n", i, p->a[i]);}free(p);
}

执行结果:
在这里插入图片描述
注意:

  1. 使用了malloc之后,记得free。
  2. 访问数组的时候,下标不要越界,否则可能引发问题。关键是编译不报错,程序可以正常运行。比如:
    在这里插入图片描述
    在这里插入图片描述

void类型的指针

在C语言中,void*(空指针)是一种特殊的指针类型,它可以指向任意类型的数据,但不包含关于所指对象类型的信息。以下是关于void*的详细解析:

核心特性

  • 通用指针void*可以存储任何类型的指针,无需显式类型转换。
  • 无类型信息:编译器不知道void*指向的数据类型,因此不能直接解引用或进行指针算术运算。
  • 大小固定:在32位系统中通常为4字节,64位系统中为8字节。

常见用法

作为函数参数(泛型编程)

用于接收任意类型的指针,实现不依赖特定类型的函数。
示例:内存复制函数

void* memcpy(void* dest, const void* src, size_t n);
  • destsrc可以是任意类型的指针,函数内部通过逐字节复制实现通用操作。
作为函数返回值

返回指向未知类型的指针,常见于内存分配函数。
示例:动态内存分配

void* malloc(size_t size);  // 返回指向新分配内存的void*
int* ptr = (int*)malloc(sizeof(int));  // 使用时需强制类型转换
实现通用数据结构

在链表、栈等数据结构中存储任意类型的数据。
示例:通用链表节点

struct Node {void* data;         // 可存储任意类型的数据struct Node* next;
};

指针转换规则

隐式转换
  • 其他指针 → void*:无需显式转换。
    int num = 42;
    void* p = &num;  // 合法:int*自动转换为void*
    
  • void* → 其他指针:在C语言中必须显式强制转换。
    int* q =  (int*)p;  // C语言中需写为 (int*)p
    
显式强制转换

使用void*前必须转换为具体类型:

int num = 42;
void* p = &num;
int value = *(int*)p;  // 先转换为int*,再解引用

使用限制

不能直接解引用
void* p = malloc(sizeof(int));
*(int*)p = 10;  // 正确:先转换为int*
// *p = 10;  // 错误:void*不能直接解引用
不能进行指针算术运算
void* p = arr;
p++;  // 错误:void*不能进行算术运算
(int*)p + 1;  // 正确:转换为具体类型后可运算

类型安全问题

若强制转换为错误类型,可能导致未定义行为:

double d = 3.14;
void* p = &d;
int x = *(int*)p;  // 错误:将double*误转为int*

典型应用场景

场景示例函数/操作
内存管理函数malloc()calloc()realloc()free() 返回/接受 void*
内存操作函数memcpy()memset()memcmp() 使用 void* 作为参数
回调函数通过 void* 传递上下文数据(如 qsort() 的比较函数)
通用数据结构链表、哈希表等存储任意类型数据的节点使用 void*

union关键字和大小端

union关键字

基本概念

  • 共用体:所有成员共享同一块内存空间,其大小由最大成员决定。
  • 特点:修改一个成员会影响其他成员的值。

示例代码

#include <stdio.h>union Data {int i;         // 4字节char c[4];     // 4字节
};int main() 
{union Data data;data.i = 0x12345678;  // 假设int为4字节// 访问不同成员printf("data.i address : 0x%x, i: 0x%X\n", &(data.i), data.i);           // 输出: 0x12345678printf("data.c[0] address : 0x%x, c[0]: 0x%X\n", &(data.c[0]), data.c[0]);     // 输出取决于大小端printf("data.c[1] address : 0x%x, c[1]: 0x%X\n", &(data.c[1]), data.c[1]);     // 输出取决于大小端printf("data.c[2] address : 0x%x, c[2]: 0x%X\n", &(data.c[2]), data.c[2]);     // 输出取决于大小端printf("data.c[3] address : 0x%x, c[3]: 0x%X\n", &(data.c[3]), data.c[3]); return 0;
}

在这里插入图片描述

大小端字节序(Endianness)

定义

  • 大端序(Big Endian):数据的高位字节存储在内存的低地址,低位字节存储在高地址。
    例如:整数 0x12345678 的存储顺序为 12 34 56 78。(从左到右,地址依次增大)
  • 小端序(Little Endian):数据的低位字节存储在内存的低地址,高位字节存储在高地址。
    例如:整数 0x12345678 的存储顺序为 78 56 34 12。(从左到右,地址依次增大)

使用union检测大小端

利用union成员共享内存的特性,可以编写一个函数检测系统的字节序:

#include <stdio.h>int isLittleEndian() {union {int i;char c;} u;u.i = 1;  // 二进制: 0x00000001// 若c为1,说明低地址存储的是低位字节(小端序)return u.c == 1;
}int main() {if (isLittleEndian()) {printf("小端序系统\n");} else {printf("大端序系统\n");}return 0;
}

原理

  • 整数 1 的二进制表示为 0x00000001(假设32位)。
  • 在小端序中,低地址存储 01,高地址存储 00 00 00
  • 在大端序中,低地址存储 00,高地址存储 00 00 01
  • 通过访问 char 成员(只占1字节),可以读取低地址的值来判断字节序。

union与大小端的应用场景

访问多字节数据的单个字节

  • 通过union可以直接操作整数的各个字节:
    union {uint16_t word;struct {uint8_t low;   // 低字节uint8_t high;  // 高字节} bytes;
    } u;u.word = 0x1234;
    printf("低字节: 0x%X\n", u.bytes.low);   // 小端序输出0x34,大端序输出0x12
    printf("高字节: 0x%X\n", u.bytes.high);  // 小端序输出0x12,大端序输出0x34
    

一些重要的编程建议

  1. 所有只读变量、宏、枚举变量都使用全部大写字母命名。
  2. 定义变量的时候尽量初始化,尤其是指针要初始化为NULL。
  3. 布尔类型是C语言中没有定义的,需要我们自己定义。
typedef enum  
{FALSE = 0,TRUE = 1
}bool;bool  bTest = TRUE;
  1. 不要使用return返回函数的局部变量。
  2. void * 指针可以被任何类型的指针赋值,但不能直接拿void * 类型的指针进行运算。如果函数入参是这个类型,那么就意味着可以接受任何指针。
	int i = 50;void * pv = NULL;int *pint = &i;pv = pint;printf("pv = %d\n", *(int *)pv);//使用的时候必须强制转换
  1. enum枚举类型的成员的值必须是int类型能表述的。与#define的区别在于#define是预处理的时候进行简单的替换,而枚举是编译的时候确定其值。枚举是一个集合,代表一类值。枚举更加安全,对于函数入参,可以判断它是不是枚举中的一个,更加成体系。

本文结束,如果对你有帮助,欢迎点赞、收藏、转发。关注!

相关文章:

  • 烟台企业做网站推广网站源码
  • 和田知名网站建设企业如何自己开发网站
  • 网站页面一般做多大网站多少钱
  • 义乌市建设银行分行网站发布外链的步骤
  • 成都广告制作厂家大连seo外包平台
  • 百度文库ai助手网页版关键词的优化方法
  • Kafka的消费消息是如何传递的?
  • 关于Makefile
  • 【动手学深度学习】4.7. 前向传播、反向传播和计算图
  • 飞算 JavaAI 插件炸场!一小时搭图书管理系统
  • Python训练营-Day40-训练和测试的规范写法
  • 10-C#的dataGridView1和datatable的使用
  • 【Pandas】pandas DataFrame merge
  • 飞往大厂梦之算法提升-day08
  • libevent(1)之基础概述
  • 网站公安网安备案查询API集成指南
  • 元宇宙时代实物建模新趋势:动态纹理映射与实时渲染方案
  • 【驱动设计的硬件基础】PCI和PCI-E
  • TongWeb替换tomcat
  • 【机器学习深度学习】多层神经网络的构成
  • MySQL深分页性能瓶颈:问题分析与解决方案
  • Linux SPI核心驱动spidev.c深度解析
  • svn域名更换,批量修改项目svn地址(linux)
  • FineBI(二)- 数据导入
  • AI时代工具:AIGC导航——AI工具集合
  • day041-web集群架构搭建