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

C语言易混淆知识点详解

C语言中容易混淆的知识点详解

C语言作为一门基础且强大的编程语言,有许多容易混淆的概念和特性。以下是C语言中一些常见易混淆知识点的详细解析:

1. 指针与数组

相似点:

c

复制

下载

int arr[10];
int *ptr = arr;
  • 都可以使用[]运算符访问元素:arr[3]ptr[3]都合法

  • 数组名在大多数情况下会退化为指向首元素的指针

区别:

特性数组指针
内存分配静态分配固定大小空间动态分配或指向已有空间
sizeof返回数组总大小返回指针本身大小
赋值操作不能直接赋值可以重新指向
作为参数传递退化为指针保持指针特性

关键点sizeof(arr)返回整个数组的字节大小,而sizeof(ptr)返回指针的大小(通常4或8字节)。

2. 指针常量和常量指针

const的不同位置含义不同:

c

复制

下载

int a = 10, b = 20;const int *p1 = &a;  // 指向常量的指针(指针可以改变,指向的值不能改变)
int *const p2 = &a;  // 常量指针(指针不能改变,指向的值可以改变)
const int *const p3 = &a;  // 指向常量的常量指针(都不能改变)

记忆技巧:从右向左读:

  • const int * → "指针指向一个const int"

  • int *const → "const指针指向int"

3. 结构体与联合体

结构体(struct):

c

复制

下载

struct Point {int x;int y;
}; // 占用sizeof(int)*2字节
  • 各成员有独立的内存空间

  • 总大小≥各成员大小之和(可能有内存对齐)

联合体(union):

c

复制

下载

union Data {int i;float f;char str[20];
}; // 占用最大成员的大小(此处为20字节)
  • 所有成员共享同一内存空间

  • 同一时间只能存储一个成员的值

4. 前置++与后置++

c

复制

下载

int i = 5;
int a = i++;  // a=5, i=6(后置:先使用值,再递增)
int b = ++i;  // b=7, i=7(前置:先递增,再使用值)

注意:在复杂表达式中使用可能引发未定义行为,如:

c

复制

下载

int i = 0;
int j = i++ + i++; // 未定义行为

5. 位运算与逻辑运算

位运算(按位操作):

c

复制

下载

&  // 按位与
|  // 按位或
^  // 按位异或
~  // 按位取反
<< // 左移
>> // 右移

逻辑运算(布尔操作):

c

复制

下载

&& // 逻辑与(短路求值)
|| // 逻辑或(短路求值)
!  // 逻辑非

关键区别

  • 位运算操作的是整数的二进制位

  • 逻辑运算操作的是表达式的真值(0为假,非0为真)

6. 数组指针与指针数组

c

复制

下载

int *p1[10];   // 指针数组:包含10个int指针的数组
int (*p2)[10]; // 数组指针:指向包含10个int的数组的指针

解析

  • p1是一个数组,其元素是指向int的指针

  • p2是一个指针,指向一个包含10个int的数组

7. 函数指针与指针函数

c

复制

下载

int *func(int);    // 指针函数:返回int指针的函数
int (*fp)(int);    // 函数指针:指向接受int参数并返回int的函数的指针

使用示例

c

复制

下载

int add(int a) { return a + 1; }
int (*fp)(int) = add;  // fp指向add函数
int result = fp(5);    // 通过函数指针调用

8. 内存分配方式

分配方式特点生命周期示例
静态存储编译时确定大小整个程序运行期间全局变量、static变量
栈存储自动分配释放函数执行期间局部变量
堆存储手动分配释放直到显式释放malloc/free分配

常见错误

c

复制

下载

char *getString() {char str[] = "hello"; // 栈内存,函数返回后无效return str;           // 错误!返回悬垂指针
}

9. 字符串与字符数组

c

复制

下载

char str1[] = "hello";    // 字符数组,可修改内容
char *str2 = "hello";     // 指向字符串常量的指针,内容不可修改str1[0] = 'H';  // 合法
str2[0] = 'H';  // 未定义行为(可能引发段错误)

关键点:字符串字面量存储在只读内存区域。

10. 预处理器与编译器

预处理器指令(编译前处理):

c

复制

下载

#define PI 3.14159    // 宏定义
#include <stdio.h>    // 文件包含
#ifdef DEBUG          // 条件编译
#endif

编译器处理:

  • 变量声明/定义

  • 函数定义

  • 类型检查等

常见混淆

c

复制

下载

#define SQUARE(x) x * x
int a = SQUARE(2+3); // 展开为2+3*2+3=11,而非预期的25

应定义为:

c

复制

下载

#define SQUARE(x) ((x)*(x))

11. 零值表示

类型零值表示
整型0
浮点型0.0
指针NULL或(void*)0
布尔型false
字符'\0'(空字符)

注意:NULL在C中通常是(void*)0,但在C++中是0nullptr

12. 类型转换

隐式类型转换(自动发生):

c

复制

下载

int i = 3.14;  // 3(截断小数部分)
double d = i;  // 3.0

显式类型转换(强制转换):

c

复制

下载

double d = 3.14;
int i = (int)d;  // C风格
int j = int(d);  // C++风格(在C中无效)

注意:强制转换可能丢失信息或导致未定义行为。

13. 可变参数函数

c

复制

下载

#include <stdarg.h>void printArgs(int count, ...) {va_list args;va_start(args, count);for(int i = 0; i < count; i++) {int val = va_arg(args, int);printf("%d ", val);}va_end(args);
}

注意事项

  • 必须至少有一个固定参数

  • 无法直接知道可变参数的数量和类型

  • 类型不安全,容易出错

14. 复杂声明解析

使用"右左法则"解析复杂声明:

  1. 从标识符开始

  2. 向右看,直到遇到)或声明结束

  3. 向左看,直到遇到(或声明开始

  4. 跳出括号,重复步骤2和3

示例

c

复制

下载

int (*(*func)(int))[10];

解析:

  1. func是一个指针

  2. 指向接受int参数并返回指针的函数

  3. 该指针指向包含10个int的数组

  4. 最终返回int

即:func是一个函数指针,该函数接受int参数并返回指向int数组的指针。

15. 未定义行为(UB)

C语言中有许多未定义行为,编译器不保证其行为:

c

复制

下载

int i = 0;
printf("%d %d\n", i++, i++); // 未定义int arr[5] = {1,2,3,4,5};
int *p = arr;
printf("%d\n", *p++ + *p++); // 未定义int a = 10;
a = a++; // 未定义

原则:避免在同一个表达式中对同一变量多次修改。

掌握这些易混淆知识点有助于编写更可靠、更高效的C代码,并避免常见的陷阱和错误。

相关文章:

  • 刷leetcodehot100返航版--哈希表5/5、5/6
  • FTP/TFTP/SSH/Telnet
  • 不小心把当前的环境变量路径覆盖掉怎么办
  • 项目管理学习-CSPM(1)
  • 手表功能RunModeTasks
  • 二叉搜索树 AVL树 红黑树 的性质
  • Java——泛型
  • Stellaris 群星 [DLC 解锁] CT 表 [Steam] [Windows SteamOS macOS]
  • rvalue引用()
  • 解决Jenkis安装、配置及账号权限分配时遇到的问题
  • 电脑怎么分屏操作?
  • 【Python】 `os.getenv()` vs. `os.environ.get()`:环境变量获取方式的本质差异解析
  • 用二进制魔法解锁复杂问题:状态压缩动态规划实战揭秘
  • 算法每日一题 | 入门-顺序结构-上学迟到
  • 9.城市基础设施更新工程
  • vulkanscenegraph显示倾斜模型(6.5)-vsg::DatabasePager
  • Linux网络编程 day4
  • 【Python】使用`python-dotenv`模块管理环境变量
  • 8.5/Q1,Charls高分经典文章解读
  • 代码随想录第33天:动态规划6(完全背包基础)
  • 机关食堂向游客开放的重庆荣昌区,“消费市场迎来历史性突破”
  • 抗战回望19︱《中国工程师学会四川考察团报告》:“将来重工业所在,以四川为最适宜之地点”
  • 侯麦:从莫扎特到贝多芬
  • 美权威人士批“特朗普对进口电影征关税”:将杀死美电影产业
  • 巴菲特掌舵伯克希尔60年后将卸任CEO,库克:认识他是人生中最珍贵的经历之一
  • 巴菲特宣布将于年底退休,“接班人”什么来头?