char*和char[]的理解

0. 问题

char* text = "abcdef ghi";
*(text+3) = 'x';     // 可以编译,但运行到这句就会出错

char a[100] = "abcdef ghi";
char* text = a;
*(text+3) = 'x';     // 可以

原因:涉及到内存分配。一个程序在C/C++编译后,占用的内存为:

  1. 常量区

  2. 全局区(静态区)

  3. 堆区

  4. 栈区

  5. 程序代码区

    内存分配具体内容可参考: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*在编译时刻赋值

参考链接:

https://blog.csdn.net/ANNaScripter/article/details/125435059?spm=1001.2101.3001.6661.1&utm_medium=distribute.pc_relevant_t0.none-task-blog-2~default~CTRLIST~Rate-1-125435059-blog-78291036.pc_relevant_3mothn_strategy_and_data_recovery&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-2~default~CTRLIST~Rate-1-125435059-blog-78291036.pc_relevant_3mothn_strategy_and_data_recovery&utm_relevant_index=1

posted @ 2023-02-24 21:33  预期  阅读(104)  评论(0)    收藏  举报