c多语言字体问题,C 语言中的文字常量区

问题:

292ba0ac402156aaf17489c622305a83.png

如果改为:

a24a8765bd27527d815f26887e545210.png

则运行正确,百思不得其解后,通过一上午的查阅资料,终于找到答案。

我做了一个测试程序,截了一个图,答案都在下面:

cdfe471ee5dce14bb554166f0b375c0c.png

答案已经全部在图上。

总结:

1. char * p = "hello";//是在编译时就要确定字符串的内容。

char q[] = "hello";//在运行时确定字符串的内容

其中,p存放的是字符串的地址,q存放的是字符串本身。所以p已经初始化之后,就不能修改。

就速度而言,显然第二种方式比第一种快。

2.C语言程序内存分配,有下列几个区:

cf52aa597f44aa7d335b410c27f1330f.png

像char * p = "hello"; 这种方式定义的字符串就是放在文字常量区的。所以定义后是不能修改的。

==============================================================

编译环境为VS2005 编译为C文件。。。

首先看下下面这段:

int main()

{

char *name = "fengkewei";

char name1[] = "fengkewei";

char *name2 = "fengkewei";

char *name3 = "woaifengkewei";

int i = 10;

int j = 10;

int k = 11;

return 0;

}

若您觉得它们应该都保存在内存中的一块地方,那请往下看。。。。

下面是编译器为各个变量分配的内存地址,由于分配在栈上 所以地址是递减的

---------------------栈区------------------------------------

+  &name 0x0013ff5c unsigned char * *+

&name1 0x0013ff48 unsigned char [10]*

+ &name2 0x0013ff3c unsigned char * *

+  &name3 0x0013ff30 unsigned char * *

+  &i 0x0013ff24 int *

+  &j 0x0013ff18 int *

+  &k 0x0013ff0c int *

---------------------------------------------------------------

&name 和&name1[] 相差20个字节 但"fengkewei"只有10个字节(带空字符) &name1[]和&name2 相差12个字节后面都正常了 都差12 为什么是12?

————————————————————————————————————————————

下面是各字符串的首地址 它们都在文字常量区里 相同也就相同了 不同则是递增分配的( 文字常量区也是递增分配的)

---------------------------文字常量区-------------------------------------------------

+  name 0x004156b8 "fengkewei" unsigned char *

+  name2 0x004156b8 "fengkewei" unsigned char *

+  name3 0x00416010 "woaifengkewei" unsigned char *

+  name1 0x0013ff48 "fengkewei" unsigned char [10]

可见name1[]是在一个不同的地方的 也就是说它就是在栈上     现在我们设置一个整型指针 int *p; p = &i; 那p的地址应该是指向i的地址,指向栈区

果然:

+  &i 0x0013ff24 int *+  p 0x0013ff24 int *

--------------------------------------------------------------------

那当我设置一个字符型指针呢?

char *p;

p = name;

+  &name 0x0013ff5c unsigned char * *

+  name 0x004156b8 "fengkewei" unsigned char *

+  p 0x004156b8 "fengkewei" unsigned char * p

则指向的是字符串的地址,也就是指向文字常量区

------------------------------------------------------------------------------------------

为什么&name与name的地址不同呢?

因为name是个字符型变量,该变量的空间分配在栈区,name指向的字符串在文字常量区,而name又是个字符型指针变量,它里面所保存的值即为字符串在文字常量区的地址,这也就是为什么指针指向的内容和指针自身的地址不同的原因了。

可见 字符串常量是放在文字常量区的, 当你初始化赋值的时候 ,这些常量就先在文字常量区开辟一段空间,保存此常量。以后相同的常量就都在这里了。

还有

char name1[] = "fengkewei";

+  name1 0x0013ff48 "fengkewei" unsigned char [10]

-  &name1 0x0013ff48 unsigned char [10]*

[0] 102 'f' unsigned char

[1] 101 'e' unsigned char

[2] 110 'n' unsigned char  [

3] 103 'g' unsigned char

[4] 107 'k' unsigned char

[5] 101 'e' unsigned char

[6] 119 'w' unsigned char

[7] 101 'e' unsigned char

[8] 105 'i' unsigned char

[9] 0 unsigned char

可以看出 name1始终是指向一个地址的 这个地址 就是栈区的地址 这就可以理解为什么书上说name1就是表示数组的首地址了。但后面的101,102,103,...代表什么呢?是ASCII码。

看看文字常量区:

+  name 0x004156b8 "fengkewei" unsigned char *

name[0] 102 'f' unsigned char

name[1] 101 'e' unsigned char

name[2] 110 'n' unsigned char

也就是说不管在栈区还是在文字常量区,都是这样保存的。

但如果是这样呢:

char name4[20];

strcpy(name4, "fengkewei");

+  &name4 0x0013fee4 unsigned char [20]*

+  &name4[0] 0x0013fee4 "fengkewei" unsigned char *

+  &name4[1] 0x0013fee5 "engkewei" unsigned char *

+  &name4[2] 0x0013fee6 "ngkewei" unsigned char *

name4[0] 102 'f' unsigned char

name4[1] 101 'e' unsigned char

可见 每个数组元素的地址都在栈区 而它们的值保存的都是相应的字符。

也就是说 这个strcpy()并没有调用文字常量区的"fengkewei",而是直接把内容放在栈区name4[20]了.

同样

char name5[20] = "fengkewei";

+  name4 0x0013fee4 "fengkewei" unsigned char [20]

+  name5 0x0013fec8 "fengkewei" unsigned char [20]

可见 这两种方式是将"fengkewei"保存在栈区的.

最后总结下文字常量区的保存方式:

char *name = "fengkewei";

+  name 0x004156b8 "fengkewei" unsigned char *   //name的值是保存在文字常量区"fengkewei"的地址

+  &name 0x0013ff5c unsigned char * *   //name自身的地址则被编译器分配在栈区

name[0] 102 'f' unsigned char     //name的第一个字符值为'f'

+  &name[0] 0x004156b8 "fengkewei" unsigned char *  //它保存在文字常量区

name[1] 101 'e' unsigned char     //第二个字符为'e'

+  &name[1] 0x004156b9 "engkewei" unsigned char *  //它也保存在文字常量区

由此可见, 字符串常量, 按保存区域的不同分为以下几种:

一种是保存在栈区 , char name5[20] = "fengkewei";  或 char name1[] = "fengkewei";

一种保存在文字常量区, 即 char *name = "fengkewei";

一种保存在全局区(静态区)

最后一种保存在堆区,即用malloc, alloc, realloc  分配内存分配的区域,可有程序员自身分配和释放

网上帖子很多 由于篇幅问题这里就不介绍了。。。

还有其他区:程序代码区 存放函数体的二进制代码。

http://hi.baidu.com/elnydtrjwrafkmr/item/49d767db2ad476f192a974d5

http://blog.csdn.net/fengkewei/article/details/2544449

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值