char*和char[]的理解
0. 问题
char* text = "abcdef ghi";
*(text+3) = 'x'; // 可以编译,但运行到这句就会出错
char a[100] = "abcdef ghi";
char* text = a;
*(text+3) = 'x'; // 可以
原因:涉及到内存分配。一个程序在C/C++编译后,占用的内存为:
-
常量区
-
全局区(静态区)
-
堆区
-
栈区
-
程序代码区
内存分配具体内容可参考:https://www.cnblogs.com/heluan/p/8652809.html
0.1 指向常量的指针和常量指针
网上对指针常量和常量指针的叫法存在一定歧义,本文都采用C++ Primer P56页所表述
书中只有指向常量的指针和常量指针,这两种,并没有指针常量的叫法
a. 指向常量的指针:
const在*的左边的,就是指向常量的指针(也可以叫做指向常量对象的指针),就不能改变指向的值
(换句话理解,这个指针指向一个地址,那个地址存放的值不能修改,但是可以让指针指向别的地址)
不能用普通指针指向常量对象,但是可以用指向常量的指针指向非常量对象(此时不能通过 指向常量的指针来改变这个非常量对象的值,但是可以通过其他途径改变这个非常量对象的值)
b. 常量指针
把*放在const之前用以说明指针是一个常量,即不变的是指针本身而非指向的那个值
*放在const的左边
常指针必须进行初始化,且值不能被修改(指针的值就是地址),但其指向的对象的值可以修改。(换句话理解,这个指针就只能指向那个地址了,不能改变,但是那个地址存放的值可以修改)
1. char*
char*是一个指向常量的指针,别人博客里叫常量指针(注意:C++ primer P56页中这个概念是另一个,即指针本身是常量,网上很多叫法和书中的相反,但书上并没有指针常量的叫法,只是叫法不同,本质要求还是一样的),即它指向的内容不能更改,但是它可以改变自身的指向(就是可以去指向另一个字符串)
char *a = "abcde";
*a = 'x'; // 不行
a = "xyz"; //可以
当直接将一个常量字符串赋值给char*, 它将在栈区开辟内存放char* text。 但在常量区开辟内存放具体的内容“abcdef ghi”, 之后再将内容的第一个字符在内存中的地址赋值给text。
这样当使用地址+下标可以访问元素,但是由于元素在常量区,却不能更改
2. char[]
对于char[]是常量指针(书中的叫法),即指针本身是常量,可以去改变里面的内容元素,但不能改变其指针的指向
char a[20] = "abcde";
a[2] = 'x'; //可以
a = "hello"; //不行
当用一个常量字符串赋值给字符数组时,会将这个字符串拷贝到栈区,这个区是可以更改的。
再让字符指针指向这个字符数组的首地址,其实指向的就是这个栈内的地址,所以可以通过地址来改变内容元素
3. char* 和 char[] 的共同点
都是指针,指向第一个字符的地址
char[]在运行时刻赋值,char*在编译时刻赋值
参考链接:

浙公网安备 33010602011771号