目录
const和指针的可能组合
- const char*p
- char const*p
- char *const p
- char const** p
- const char** p
- const char *const *p
- cosnt char ** const p
const在*左侧:修饰指针所指向的内容*p,不能修改指针所指向地址上存储的数据(内容),可以修改指针存储的地址(一个指针变量p上面能且只能存放一个固定地址)
const在*右侧:修饰指针本身p,不能修改指针存储的地址(一个指针变量p上面能且只能存放一个固定地址),可以修改指针所指向地址上存储的数据(内容)
一级指针部分
1、const char* p = "abc":“abc”不能被修改,但是p可以指向"def"
2、char const* p = "abc":同上
3、char* const p = "abc":"abc"可以被修改,但是p指向的永远是原"abc"所在空间
二级指针部分
4、const char **p = &str:p是一个存放常量字符指针str地址的非常量字符指针,const修饰*p,但是*p仍可以修改,这是因为c语言中“只读”性质主要应用于变量本身而不是其所引用或间接引用到的数据(后面有详细分析):
#include <stdio.h> int main() { const char* str1 = "abc"; const char* str2 = "def"; const char* str3 = "ghi"; char const ** p = &str1; p = &str3;//修改指向,正确 *p = str2;//修改内容,正确 return 0; }
5、char const **p = &str:同上
6、const char* const *p:p是一个存放常量字符指针str地址的常量字符指针,第一个const修饰*p但是*p仍可以修改,加上第二个cosnt构成双重const则此时*p不能修改,这是因为此时只读性质被应用于两层(后面有详细分析):
#include <stdio.h> int main() { const char* str = "Hello"; const char* newStr = "World"; const char* const* p = &str; p = &newStr;//修改指向,正确 *p = newStr;//修改内容,错误 return 0; }
7、const char ** const p =&str:p是一个存放常量字符指针str地址的常量字符指针,第一个const修饰*p但还是因为只读所以*p仍能被更改,第二个const修饰p所以p不能被更改:
#include <stdio.h> int main() { const char* str = "Hello"; const char* newStr = "World"; const char ** const p = &str; p = &newStr;//修改指向,错误 *p = newStr;//修改内容,正确 return 0; }
注意事项:
1、const是左结合的,优先选择左边
2、当在一个指针声明中有两个或以上的*时,这表明这是一个多级指针,即使它们是分开的
3、无论是二级指针还是一级指针,只要const在全部*左侧就是修饰*p(p可以是一级也可以是二级)*p不能更改(多级除外),只要const在全部*右侧就是修饰p(p可以是一级也可以是二级)p不能被修改,
4、如果是const在*之间的双重const修饰则对于二级指针p而言它的*p不可以被修改
对“只读”的理解
在C语言中,当使用const修饰一个变量时,这意味着该变量是只读的,即不能通过该变量来修改其所引用的数据。但是需要注意以下几点来正确理解“只读”性质:
1、指针本身的只读性:当你声明一个指向常量数据的指针时(比如const char* ptr
),这意味着你不能通过这个指针来修改所指向地址上存储的内容,例如:
const char* ptr = "Hello";
*ptr = 'h'; // 这将导致编译错误,因为ptr是一个常量指针。
2、 双重间接引用的情况:在二级或更高级别间接访问情况下(const char** p
),如果想要确保无法通过间接访问修改数据,则应使用双重 const 修饰符(const T * const * p)
此时
“只读”性质既应用于第一层解引用操作符所得到的值也应用于第二层(二级指针的*p不能修改了)
3、仅对直接声明对象有效:在C语言中,“只读”属性主要适用于直接声明为常量或被显式转换为常量类型。如果您有一个非常数对象,并且从它派生出了另外一个对象或者传递给函数等操作后可能会改变它们,则“只读”属性不再起作用
~over~