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

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

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>首先,用户的问题是:“我想理解C语言const char *char *区别 请问C语言const char *char *区别”。这是一个关于C语言指针的查询,具体是const char *char *区别。 根据系统级指令: - 所有行内数学表达式必须使用$...$格式,但这里没有数学表达式,所以不需要。 - 独立公式必须使用$$...$$格式,但这里可能不需要。 - LaTeX语法正确:确保任何LaTeX都正确。 - 使用中文回答:整个回答必须用中文。 - 生成相关问题:在回答结束时,生成相关问题。 - 回答中引用的段落末尾自然地添加引用标识,例如:[^1]。参考了三个引用,我需要检查这些引用是否相关。 用户提供的引用: - 引用[1]: 关于const char *point1、char *const point2等的区别。 - 引用[2]: 详细解释了const char *ptr,包括代码示例。 - 引用[3]: 关于const char *字符切割的实现。 用户的问题焦点是const char *char *区别,所以引用[2]最相关,因为它直接解释了const char *ptr。 我的回答结构: - 结构清晰,帮助用户逐步解决问题。 - 回答真实可靠:基于C语言标准。 - 使用中文。 关键点: - char *:指向字符的指针,可以修改指针所指向的内容指针本身。 - const char *:指向常量字符的指针,不能通过该指针修改所指向的内容,但可以修改指针本身(即改变指向的地址)。 从引用[2]: - const char *ptr:不能通过ptr修改指向的内容,但可以改变ptr的指向。 - 例如,ptr[0] = 'A' 会编译错误,但ptr = name 是允许的。 对比char *: - char *ptr:可以修改内容指向。 步骤: 1. **解释char *** - 定义:指向字符数据的指针。 - 特性:可以修改指针指向的数据(如ptr[0] = 'A'),也可以修改指针本身(如ptr = new_address)。 2. **解释const char *** - 定义:指向常量字符数据的指针。 - 特性:不能通过该指针修改数据(保护数据不被修改),但可以修改指针的指向。 - 为什么使用:用于函数参数,确保函数不会修改传入的字符串,例如在strlen或printf中。 3. **区别总结:** - 可修改性:char *允许修改内容;const char *不允许修改内容。 - 指针本身:两者都可以修改指向(除非有其他const修饰)。 4. **代码示例:** - 从引用[2]中提取或简化代码来演示。 - 例如: ```c char str[] = "Hello"; char *ptr1 = str; // char *: can modify content and pointer ptr1[0] = 'h'; // OK ptr1 = "World"; // OK const char *ptr2 = str; // const char *: cannot modify content // ptr2[0] = 'h'; // Compile error ptr2 = "World"; // OK, can change pointer ``` 5. **常见用途:** - const char *:常用于字符串字面量或只读数据。 - char *:用于可修改的字符串。 6. **生成相关问题:** - 在结束时,生成2-3个相关问题,如: - 1. char *const const char * 有什么区别? - 2. 如何在函数中使用 const char * 参数? - 3. const char *char const * 是否相同? 7. **添加引用标识:** - 在回答中,如果引用特定段落,末尾添加[^n]。 - 例如,提到引用[2]时添加[^2]。 完整回答结构: - 引言:直接回答问题。 - 详细解释:分点解释。 - 代码示例。 - 总结区别。 - 相关问题。 确保语言流畅、专业。</think>### C语言中`const char *`与`char *`的区别 在C语言中,`char *``const char *`都是指向字符数据的指针类型,但它们在**可修改性**上有关键区别。以下是逐步解释,帮助您理解两者的核心差异。我会结合代码示例说明,确保回答清晰可靠。 #### 1. **`char *`(可修改指针)** - **定义**:`char *`是一个指向字符数据的指针,允许修改指针所指向的内存内容(即数据本身),也允许修改指针本身(即改变指向的地址)。 - **特性**: - 可以修改数据:例如,通过指针解引用或索引操作更改字符串内容。 - 可以重定向指针:例如,将指针指向另一个字符串。 - **代码示例**: ```c #include <stdio.h> int main() { char str[] = "Hello"; // 可修改的字符数组 char *ptr = str; // char *指针 ptr[0] = 'h'; // 允许修改数据: 将'H'改为'h' printf("修改后: %s\n", ptr); // 输出: hello ptr = "World"; // 允许重定向指针 printf("重定向后: %s\n", ptr); // 输出: World return 0; } ``` - 这里,`ptr`可以自由修改数据(`ptr[0] = 'h'`)指针本身(`ptr = "World"`)。 #### 2. **`const char *`(指向常量的指针)** - **定义**:`const char *`是一个指向常量字符数据的指针,**不能**通过该指针修改所指向的内存内容(数据是只读的),但**可以**修改指针本身(改变指向的地址)。 - **特性**: - 数据不可修改:尝试通过指针修改内容会导致编译错误,保护数据不被意外更改。 - 指针可重定向:可以将指针指向其他常量字符串。 - **常见用途**:用于函数参数传递只读数据,例如`printf`或`strlen`函数,确保函数内部不会修改原始数据[^2]。 - **代码示例**: ```c #include <stdio.h> int main() { char str[] = "Hello"; const char *ptr = str; // const char *指针 // ptr[0] = 'h'; // 编译错误! 不能修改数据 printf("原始数据: %s\n", ptr); // 输出: Hello ptr = "World"; // 允许重定向指针 printf("重定向后: %s\n", ptr); // 输出: World return 0; } ``` - 注意:虽然`ptr`不能修改数据,但如果原始数据不是常量(如`str[]`),其他指针(如`char *`)仍可修改它[^2]。 #### 3. **核心区别总结** | 特性 | `char *` | `const char *` | |---------------------|------------------------------|-------------------------------| | **数据可修改性** | 可以修改指向的数据 | 不能修改指向的数据(只读) | | **指针可重定向性** | 可以改变指针指向的地址 | 可以改变指针指向的地址 | | **编译保护** | 无保护,操作自由 | 编译器阻止数据修改操作 | | **典型应用场景** | 动态构建或修改字符串 | 传递只读数据(如字符串字面量) | - **关键点**:`const char *`的`const`修饰的是指针指向的数据,而非指针本身。这意味着指针可以指向新地址,但不能通过它修改数据。这与`char *const`(指针本身不可修改)不同[^1]。 - **为什么重要**:使用`const char *`能提高代码安全性可读性,避免意外修改数据,尤其在多线程或API设计中[^2]。 #### 4. **实际应用示例** 假设您有一个函数处理字符串: ```c void print_string(char *str) { // 可能修改数据 str[0] = 'X'; // 允许操作 printf("%s\n", str); } void safe_print(const char *str) { // 只读访问 // str[0] = 'X'; // 编译错误,保护数据 printf("%s\n", str); } int main() { char buffer[] = "Test"; safe_print(buffer); // 安全传递只读数据 return 0; } ``` - 这里,`safe_print`使用`const char *`确保函数不会修改输入数据,这是良好的编程实践[^2]。 ### 相关问题 为了帮助您深入理解,以下是几个相关问题: 1. `char *const` `const char *` 有什么区别?[^1] 2. 如何在C语言中使用`const char *`处理字符串切割(如IP地址解析)?[^3] 3. `const char *` 与 `char const *` 是否完全相同?
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值