赞
踩
字符串常量储存在.rodata,只读数据区
char* a = "Hello";
// 或者
const char* a = "Hello"
printf("Hello");
// 这里两个Hello的地址都是同样的 通过反汇编可知
1.char* a
这种写法是C语言时代的
2.const char* a
是CPP语言的
在CPP中使用第一种写法会报错,在C中并不会报错,所以即使修改值也不会引发编辑器报错,但是在运行时
会报错,因为修改了只读区域,产生了异常控制流,强制停止进程运行。
所以我个人觉得CPP
对此进行了改进,在编辑器层面避免了这种不必要的写法(修改了就一定出问题的写法,肯定得从编译时就抹杀掉。。),因此字符串
变成了字符串常量
既const char*
char b[] = "Hello"
字符串数组
是可以修改的,因为是储存在栈中的,在上面的反汇编中可以看出,它也是中只读区域将Hello
复制到栈中的。所以这就是为什么const char* 的可以赋值给 char []。
const char*a = "Hello";
a = "World";
若想改变a的值,那就得赋予它同样的类型,就是得同样是只读区域
的值(地址),因此想要单独修改某个字符是做不到的。
// a[i] = 'd';
// a+1 = 'c';
类似这种操作都是行不通的,类型不符合的同时操作也非法,修改只读区域
同时注意一点,一个变量它是有两个属性的,一个是值,一个是地址。
一般VS不会标识出地址
地址和值都可以被打印出来。
一般来讲,值是地址的内容。但是不可以认为值就是数值之类的东西例如(1,2,3,a,b),有时候值也会是一个地址。就如同上面的char a*
它值就是一个地址。
而且一般值是数值之类的东西的话,会直接放在寄存器上,所以它也就没有了地址。例如
int a = 1;
这个时候a是没有地址的,但是如果你去打印a的地址时,它就会把a的内容放到内存上(栈上),所以a就有了地址。有点像量子你观测我我就存在。。。但其实不是的哈,只是设计如此,只有需要地址时,函数内局部变量才会被放到栈上,或者寄存器不够用的时候也会将超出的变量放置在栈上。
更多介绍
字符串常量引起的思考
一个变量它是有两个属性的,一个是值,一个是地址
接着上说讲,我们在vs中见到的都是值,这个值其实都是存放在栈中或者直接存放在寄存器中的,也如同上面所说的,如果我们不去打印地址,那么它一般不会将我们的值存放到栈上的。还有一种情况就算寄存器用完了,也会放到栈上。以下的讨论我们默认都认为我们的值是直接放在寄存器中的。明白了这一点,那么我们对指针的操作就会简单很多。
其实好像也没有什么不同,毕竟寄存器的值都是从内存上读取的。
int* a1 = (int*)malloc(4); int* a2 = (int*)malloc(4); *a1 = 1; *a2 = 2; // 假设 a1的值为0x00000000000000a1,a2的值为0x00000000000000a2。为了简写后面我省略一下。 __int64 * bp1 = (__int64*)malloc(16); // 首先我们申请两个可以容纳地址大小的空间 *bp1 = (__int64)a1; // *bp1,寻址,找到*bp1地址处,然后设置为a1的值,因为a1的值是个地址,且地址处的值是1。(__int64)a1,强制将a1的值表示为 __int64 整数类型,这样才可以设置进入内存。 __int64* bp2 = (__int64*)(*bp1); // 将我们的值转化为地址。(*bp1)先是将值取出,此时值为0x00a1。(__int64*)(*bp1)强制将值当作地址对待。0x00a1值是一个__int64类型的整数,编译器无法识别,所以我们要告诉它。 printf("a1 = %d\n", *bp2); // *bp2,寻址,找到*bp2地址处的值,然后显示出来。 //printf("a1 = %d\n", *(__int64*)(*bp1)); bp1 = bp1 + 1; // 寄存器上的值移动一个__int64单位字节 *bp1 = (__int64)a2; printf("a2 = %d\n", *(__int64*)(*bp1)); // 结果 //a1 =1 //a2 = 2
1-4行
在堆上申请了两个存放数值的空间,a1/a2的值是堆的地址。然后我们寻址,找到a1地址处,然后设置这个地址处的内容,也就是*a1表示的意思了。
6-13行
这个是为了验证上面所提的,一个变量两个属性。
下面这个是个简单版本
int* a1 = (int*)malloc(4);
int* a2 = (int*)malloc(4);
*a1 = 1;
*a2 = 2;
int** bp = (int**)malloc(16);
*bp = a1;
printf("a1 = %d\n", **bp);
bp = bp + 1;
*bp = a2;
printf("a2 = %d\n", **bp);
个人觉得这个表示的不是很清晰,就是后面在去看,可能就有些看不懂了,得捋一下。当然了,平常写代码肯定是简单版本。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。