6月4日 10:34

C语言 const 关键字怎么用?指针组合和实战场景详解

const 告诉编译器"这个值不许改"——但只限于编译期检查,运行时通过指针强转照样能绕过,所以 const 更像是"程序员之间的约定"而非硬件级的不可变。

最核心的考点是 const 和指针的组合,读法从右往左:const int *p → p is a pointer to int const(指向的值不能改);int *const p → p is a const pointer to int(指针本身不能改)。一个快速判断法:const 在 * 左边修饰数据,在 * 右边修饰指针。

实际项目中最有价值的用法是函数参数加 constvoid process(const char *input, const int *data, size_t len),既防止函数内部意外修改输入数据,又让调用者一看签名就知道"这个函数不会动我的数据"。

c
// 最实用的 const 模式:只读参数 size_t str_len(const char *s) { size_t n = 0; while (s[n]) n++; return n; } // 调用者知道 s 不会被修改,编译器也敢做优化

追问

const 变量和 #define 宏有什么区别?

const 变量有类型、有作用域、调试器能看到名字和值。#define 是预处理器的文本替换,没有类型、没有作用域、调试时只看到魔法数字。但 const 变量在 C 里不是真正的编译期常量——不能用来定义数组大小(VLA 除外),也不能用在 case 标签里,这是 C 和 C++ 的重大区别。

const 指针到底能不能绕过?

能。const int x = 10; int *p = (int*)&x; *p = 20; 编译通过,但修改 const 对象是未定义行为——编译器可能把 x 的值缓存在寄存器里,修改内存后读到的还是旧值。所以能绕过不代表该绕过,UB 的 bug 比 const 违规难查一百倍。

函数返回 const 指针有什么用?

防止调用者通过返回的指针修改内部数据。典型场景:const char* get_error_msg(int code),返回指向静态字符串的指针,加 const 让调用者知道不该写这块内存。如果不加 const,调用者 ((char*)get_error_msg(0))[0] = X 就能改掉内部字符串,出问题时很难定位。

const 和 volatile 能同时用吗?

能,而且嵌入式开发中很常见:const volatile uint32_t *hw_reg = (void*)0x4000;——const 表示程序不该写这个寄存器,volatile 表示每次读都必须从内存取(不能缓存),因为硬件可能随时改变它的值。两者修饰的是不同层面:const 约束程序员,volatile 约束编译器。

标签:C语言