const char * 和 char const * 和 char * const 区别

本文通过示例代码详细解析了C语言中const关键字的不同用法,包括如何使用const来保护指针所指向的数据不被修改,以及如何将指针本身设置为不可重新赋值。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

zz from: http://blog.chinaunix.net/uid-293226-id-2134198.html

我们都用过const 修饰符修饰一个变量,而且我们知道使用const修饰之后,这个变量相当于常量了,他的值在代码其他部分不能再修改,这对于函数调用时候,防止错误的修改原本不应修改的变量起到很大作用,举个例子,加入A函数调用B函数进行字符串处理,A把字符串的地址传递给BB在处理过程中误修改了字符串的地址,导致程序出错,有时候这种错误很难找到,这时候我们就可以使用const关键字。

              可是对于指针的情况,我们不想修改指针指向的地址,但是允许修改指针指指向的地址中的值,该怎么做呢,可以这么理解这段话,如果 char * a = ptr,那么a不能在指向其他的地址,但是对于*a的赋值是可以的。那么如果我们写const char *或者char const *或者

char * const,哪一个是我们需要的呢?看一段代码。

1 #include

2 int main(void)

3 {

4     char buf[] = "hello world";

5     char buf2[] = "world hello";

6     const char* a = buf;

7     char const* b = buf;

8     char* const c = buf;

9     //*a = 'x';

10     //*b = 't';

11     *c = 't';

12     a = buf2;

13     b = buf2;

14     //c = buf2;

15     printf("a is %s\nb is %s\nc is %s \n", a, b, c);

16     return 0;

17 }

如果我把第8行第9行的注释去掉,编译的时候会发生如下错误:(编译环境gcc

test.c: In function `main':

test.c:9: error: assignment of read-only location

test.c:10: error: assignment of read-only location

如果14行注释去掉会发生如下错误:

test.c: In function `main':

test.c:14: error: assignment of read-only variable `c'

好了我么总结一下,const char *char const* 效果一样,都是不允许修改指针指向的地址空间的值,即把值作为常量,而char * const则是不允许修改指针自身,不能再指向其他地方,把指针自己当作常量使用。需要注意的是,使用char * const 定一个常量指针的时候一定记得赋初始值,否则再其他地方就没法赋值了。

<think>嗯,用户之前问了关于isKeyDown函数的问题,现在又转向了const char*char*区别。可能用户在学习C或C++,尤其是涉及到指针字符串处理的部分。需要先确认用户的基础,但根据之前的问题,可能已经对指针有一定的了解,现在需要更深入的解释。 用户的问题看起来是要区分这两种指针类型的区别,可能需要从语法、语义以及使用场景来讲解。首先,我需要明确const char*char*在声明上的不同,const的位置决定了什么。然后要解释常量指针指针常量的区别,不过这里可能用户混淆了这些概念,需要澄清。 接着,用户可能想知道为什么要有这两种不同的类型,比如在函数参数中使用const char*可以防止修改传入的字符串,提高代码的安全性可读性。同时,char*则允许修改指向的内容,适用于需要操作字符串的情况。 可能用户在实际编程中遇到了问题,比如尝试修改const char*指向的内容导致编译错误,或者不理解为什么某些函数参数要求使用const char*。需要举一些例子来说明,比如字符串字面量的存储位置,尝试修改它们会导致未定义行为,而使用const可以避免这种错误。 另外,用户可能对内存管理有疑问,比如const char*是否指向只读内存区域,而char*指向可修改的内存。需要解释字符串字面量的存储位置,以及动态分配内存时的情况。 还有可能用户在学习函数参数传递,比如在C++中,函数参数声明为const char*可以接受常量字符串非常量字符串,而char*只能接受非常量的,这样可以提高函数的通用性。同时,强调类型安全的重要性,避免意外修改数据。 需要检查是否有常见的误区,比如const char*char const*是否相同(是的,它们相同),而char* const则是不同的概念,即指针本身是常量,但指向的内容可以修改。但用户的问题可能主要集中在内容是否可变,而不是指针本身是否可变。 总结来说,回答应该包括: 1. 语法上的区别const的位置含义。 2. 语义上的区别,能否修改指向的内容。 3. 使用场景,比如函数参数、字符串字面量、动态内存等。 4. 注意事项,如修改const数据的后果,类型安全的好处。 5. 示例代码,展示正确错误的用法,帮助用户理解。 还需要考虑用户可能的后续问题,比如如何转换const char*char*,或者何时使用哪种类型,是否涉及内存分配等问题。因此,在回答中要涵盖这些潜在的问题点,确保解释全面且易于理解。</think>--- `const char*` 与 `char*` 是 C/C++ 中处理字符串的两种指针类型,核心区别在于**能否通过指针修改指向的内存内容**。具体分析如下: --- ### 🔑 核心区别 | 类型 | 能否修改指针指向的内容 | 能否修改指针自身指向的地址 | |-----------------|------------------------|----------------------------| | `char*` | ✅ 允许 | ✅ 允许 | | `const char*` | ❌ 禁止 | ✅ 允许 | | `char* const` | ✅ 允许 | ❌ 禁止 | --- ### 📝 语法解析 #### 1. `char* ptr`(非常量指针) - **特点**:指针指向的内容均可修改 - **典型用法**:动态字符串操作 ```cpp char str[] = "Hello"; // 栈内存可修改 char* ptr = str; ptr[0] = 'h'; // 合法:修改内容 ptr = "World"; // 合法:修改指针指向 ``` #### 2. `const char* ptr`(常量内容指针) - **特点**:禁止通过指针修改内容,但可改变指针指向 - **典型用法**:只读字符串处理 ```cpp const char* ptr = "Hello"; // ptr[0] = 'h'; // 编译错误:内容不可修改 ptr = "World"; // 合法:修改指针指向 ``` #### 3. `char* const ptr`(常量指针) - **特点**:指针不可重定向,但可通过指针修改内容 ```cpp char str[] = "Hello"; char* const ptr = str; ptr[0] = 'h'; // 合法 // ptr = "World"; // 编译错误:指针不可修改 ``` --- ### 🚨 关键注意事项 1. **字符串字面量的特殊性质**: ```cpp char* ptr = "Hello"; // 危险!字符串字面量存储在只读区 // ptr[0] = 'h'; // 运行时错误(未定义行为) ``` ✅ 正确做法: ```cpp const char* ptr = "Hello"; // 明确声明不可修改 ``` 2. **函数参数设计准则**: - 输入参数:优先使用 `const char*`(保证数据安全) ```cpp void printString(const char* str); // 承诺不修改内容 ``` - 输出参数:使用 `char*`(需要修改内容时) ```cpp void modifyString(char* buffer); ``` --- ### 🔧 类型转换规则 | 操作 | 合法性 | 说明 | |--------------------------|----------|-------------------------------| | `char*` → `const char*` | ✅ 自动 | 安全转换(权限收缩) | | `const char*` → `char*` | ❌ 需强制 | 危险!可能引发写入只读内存错误 | ```cpp const char* cptr = "test"; // char* ptr = cptr; // 编译错误 char* ptr = const_cast<char*>(cptr); // 强制转换(慎用!) ``` --- ### 🛡️ 最佳实践 1. **默认使用 `const char*`**:除非明确需要修改内容 2. **搭配 `const` 修饰函数参数**:增强接口安全性 3. **动态内存操作时使用 `char*`**: ```cpp char* buffer = new char[100]; strcpy(buffer, "Dynamic"); delete[] buffer; ``` --- 掌握这些区别可有效避免内存访问错误,提升代码健壮性。建议结合调试器观察内存权限变化,加深理解。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值