C语言中const修饰指针时,核心规则是“左const管内容,右const管指针”:当const位于*左侧(如const int *pint const *p),修饰指针指向的内容,内容不可修改但指针可指向新地址;当const位于*右侧(如int *const p),修饰指针本身,指针不可变但指向的内容可修改;若两者同时存在(如const int *const p),则指针和内容均不可修改。

在C语言中,const关键字用于修饰指针时,其位置不同会导致完全不同的语义。理解const修饰指针的规则对编写安全、健壮的代码至关重要。

const修饰指针的三种主要情况

1. const int *pint const *p(指针指向的内容是常量)

  • 含义const修饰的是指针指向的内容(*p
  • 不能通过指针修改指向的内容
  • 指针本身可以指向其他地址
int a = 10, b = 20;
const int *p1 = &a;  // p1可以指向其他地址,但不能修改*p1
p1 = &b;             // 正确:指针可以修改指向
// *p1 = 30;         // 错误:不能修改指向的内容

特点const*左边,修饰的是指针指向的数据。

2. int * const p(指针本身是常量)

  • 含义const修饰的是指针本身(p
  • 不能修改指针的指向
  • 可以通过指针修改指向的内容
int c = 10, d = 20;
int *const p2 = &c;  // p2不能指向其他地址,但可以修改*p2
// p2 = &d;          // 错误:指针不能修改指向
*p2 = 30;            // 正确:可以修改指向的内容

特点const*右边,修饰的是指针变量本身。

3. const int * const pint const * const p(指针本身和指向的内容都是常量)

  • 含义const同时修饰指针本身和指针指向的内容
  • 不能修改指针的指向
  • 不能通过指针修改指向的内容
int e = 10, f = 20;
const int *const p3 = &e;  // 既不能修改指针指向,也不能修改指向的内容
// p3 = &f;          // 错误:不能修改指针指向
// *p3 = 30;         // 错误:不能修改指向的内容

重要规则和记忆方法

  • "左const管内容,右const管指针"const靠近谁,就修饰谁

    • const int *pconst靠近int,修饰指向的内容
    • int *const pconst靠近*,修饰指针本身
  • 等价写法const int *pint const *p 是等价的

实际应用场景

  1. 保护函数参数不被修改

    void print_string(const char *str) {
        // 不能修改str指向的内容
        printf("%s", str);
    }
    
  2. 定义指向常量的指针(如字符串常量):

    const char *days[] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
    // days[0][0] = 'X'; // 错误:不能修改字符串常量
    
  3. 硬件寄存器映射(指针地址固定,但内容可变):

    volatile uint32_t *const uart_status = (uint32_t *)0x10000000;
    *uart_status = 0x01;  // 可以修改寄存器值
    // uart_status = ...;  // 错误:指针地址不可变
    

注意事项

  1. 从非const指针到const指针的转换是允许的

    int a = 10;
    int *p1 = &a;
    const int *p2 = p1;  // 正确
    
  2. 从const指针到非const指针需要强制转换(不推荐,可能导致未定义行为):

    const int a = 10;
    const int *p1 = &a;
    int *p2 = (int *)p1;  // 需要强制转换
    // *p2 = 20;  // 未定义行为,可能导致程序崩溃
    
  3. 字符串字面量默认具有const属性

    // 不推荐:char *str = "Hello";
    const char *str = "Hello";  // 正确
    

总结

修饰方式语义不能修改能修改
const int *p指向内容是常量指向内容指针指向
int *const p指针本身是常量指针指向指向内容
const int *const p指针和指向内容都是常量指针指向和指向内容

理解const修饰指针的规则是C语言编程中的重要基础,正确使用可以大大提高代码的安全性和可维护性。