字符串常量

来源:互联网 发布:织梦cms基于什么框架 编辑:程序博客网 时间:2024/04/26 07:31

问题的提出:

 

字符串指针初始化后,使用gets函数会出错!

 

#include<stdio.h>int main(){       char *ch="abcd";       gets(ch);       puts(ch);       return 0;}


 

有关资料:(百度知道)

 

**************************************************************

char *ch ="abcd";

 

ch指向的是一个字符串常量,常量不可修改

 

追问:双引号内的字符,称为字符串常量。

如果初始化字符数组,也是用的字符串常量,为何可以修改呢?

 

回答:ch是指针变量,它只负责指向某个地址,恰好它指向的是一个常量,所以不能修改所指向的常量的值;字符数组占用一定的内存空间,字符数组的初始化和赋值,其实是将字符串常量写到他自己的内存空间中,而等号右边的无名字符串常量并不会被改变,改变字符数组的值也不会改变那个无名字符串常量的值。 好绕口。。。。。。。。。总之一个原则,只有变量才可以被修改,常量不可以被修改。

 

追问:我能否这样理解,

程序中出现的没有赋给某个变量的双引号内的字符串,是属于静态存储类。把指针初始化到指向这个静态存储的字符串,只是引用了这个字符串。

而初始化字符数组为这个字符串,是说把这个字符串复制到了一个分配好的变量存储空间,之后再修改的,就是数组里的字符。

 

回答:可以这么理解

 

提问者评价

谢谢!

*********************************************************************

 

 

上述描述中,有一句话:“而初始化字符数组为这个字符串,是说把这个字符串复制到了一个分配好的变量存储空间,之后再修改的,就是数组里的字符。”

对于指针,我们无法验证那个区域的是常量还是变量,但是对于数组,我们可对其初始化后再修改其中某个值来对比是常量还是变量。

 

代码设计:

 

#include<stdio.h>int main(){       chara[10]="abcde";       a[1]='z';       return 0;}


设置断点,debug,反汇编,单步跟踪……过程如下:

 

4:        chara[10]="abcde";0040E148  mov         eax,[string"abcde" (00422fc8)]0040E14D  mov         dword ptr[ebp-0Ch],eax0040E150  mov         cx,word ptr [string"abcde"+4 (00422fcc)]0040E157  mov         word ptr [ebp-8],cx0040E15B  xor         edx,edx0040E15D  mov         dword ptr [ebp-6],edx

从上面可以看出”abcde”是存储在地址00422fc8h中的,查看一下:


00422FC8  61 6263 64 65 00 00 00  abcde...


果然如此,但是我们还不知道这是常量还是数组的变量空间,所以继续:

 

5:       a[1]='z';0040E160  mov         byte ptr [ebp-0Bh],7Ah


此时 EBP= 0018FF48,但是题意中是[ebp-0Bh],所以我们查看ebp-0Bh=0018FF48-0bh=0018FF3d中的内容。

 

0018FF3C  61 6263 64 65 00 00 00  abcde...

 

当执行完a[1]='z';指令后,

 

018FF3C  61 7A63 64 65 00 00 00  azcde...

我们可以看到,值已经改变了,

 

再回去看00422fc8内的内容:

 

0422FC8  61 62 63 64 65 00 00 00  abcde...


没有变!

 

从上面的实例中可以看出,0422FC8中的是字符串常量,而0018FF3C中的是变量,也即a数组的空间区域。

 

 

 

引出问题:

 

对指针指向的内存区域赋值:

 

#include<stdio.h>int main(){       char *a="abcdefghij";       printf("1\n");       a[1]='a';       printf("2\n");       gets(a);       return 0;}


结果:出错。而且根据printf设置的标记,确定是"a[1]='a';"这条指令出错。

 

//b指向字符串常量,c指向a数组区域#include<stdio.h>int main(){       char a[10]="abcdef";       printf("%d\n",a);       char *b,*c;       c=(char *)(1638204);// 18ff3b       c[1]='z';       printf("%c  1\n",c[1]);       b=(char *)(4333596);// 0042201c       b[1]='z';       printf("2\n");       return 0;}


原创粉丝点击