由于网上介绍内存分配的比较简单 自己顺便写了一份

由于刚接触C  若有问题 请指出 欢迎讨论

编译环境为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/summy00/blog/item/501a16dae1fe96deb7fd487d.html

(常量之所以称为“文字常量”,其中“文字”是指我们只能以它的值的形式指代它,“常量”是指它的值是不可变的。同时注意一点:文字常量是不可寻址的(即我们的程序中不可能出现获取所谓常量20的存储地址&20这样的表达式),虽然常量也是存储在内存的某个地方,但是我们没有办法访问常量的地址的。
常量是有类型的:
1、 字符型char:一个字节表示,通常表示单个字符或小整数,字符型常量用一对单引号‘ ’夹着一个字符表示。
(1)可打印字符常量表示:
‘a’    ‘2’ ‘,’    ‘ ’
字符常量在内存中的存储格式依赖于ASCП码表的。
(2)不可打印字符常量,通过斜杠“/”表示:
‘/n’   换行符     ‘//’ 反斜杠 ‘/t’   水平制表符 ‘/0’ 空(NULL)字符
2、 整型int:一个机器字长度的整数值。
短整型short:半个机器字长度的整数值。
长整型long:一个或两个机器字长度的整数值。
在32位机器中,int和long通常相同。
(1)上面提到的char字符型,也可看作长度为一个字节的字符型整数。
通过下面这个小例子,可以看到char型数据,不同初始化方法,内存格式也是不同的。
char a=’1’;
cout<<a+1<<endl; //输出结果为50,参照ASC表,字符常量’1’在内存中是十进制数49
char b=1;
       cout<<b+1<<endl;//输出结果为2
       实际上,字符常量还可以初始化int、long等类型数据,例如:
       int c=’1’;
       cout<<c+1<<endl;//输出结果也是50
       而:
       char a=’1’;
       cout<<a<<endl;//输出结果为1
       int a=’1’;
       cout<<a<<endl;//输出结果为49
       这些区别需要引起我们的注意。
(2)整数常量可以使用十进制、八进制、十六进制表示,例如
       20(十进制)024(八进制)0x24(十六进制,也可写做0X24,“x”大小写无所谓)
(3)整型常量可以有符号,也可以无符号,例如:
       一个8位有符号char:-128~127
       一个8位无符号char:0~255
说明:缺省的整型常量是int型的,我们可以使用”L”或”l”后缀强制把整型常量表示成long型,另外也可加后缀”U”或”u”指定成无符号数,例如:128U、1024UL、1L、8Lu
3、 浮点型float:一个字长度的单精度浮点数
双精度double:两个字长度的双精度浮点数
长双精度long double:3个或4个字长度的扩展精度浮点数
(1)       浮点常量可以写成科学计数法或普通十进制数
(2)       浮点常量缺省为double型,可以加后缀“F”“f”“L”“l”修饰为单精度浮点数或扩展精度浮点数,但是只能修饰十进制表示的浮点数。还有跟整型常量不一样的地方是,浮点数部分正负,也就是说不能使用“U”“u”后缀。
例如:3.14159F 0.1f  12.345L        0.0    3e1  1.0E-3  1.0L
4、 布尔常量boolean:true或false
5、 字符串常量:比较特殊的一种类型,它不是内置或基本的数据类型,实际上就是字符常量数组,它由字符串文字本身以及编译器加上的表示结束的空(NULL)字符组成。
字符串常量“Ab”在内存中的实际格式是’A’’b’’/0’
如果程序中”two””Some”紧邻,C++编译器会把它们连在一起,并在最后加上一个空字符,即输出为”twosome”
字符串常量还可换行表示,只需在换行的地方加上“/”,例如:
“abc/
de/
fgh”
实际上就是表示”abcdefgh”

文章出处:DIY部落(http://www.diybl.com/course/3_program/c++/cppjs/20091021/179797.html))

文字常量区与栈区分析相关推荐

  1. 文字常量区和栈区考点

    求以下程序输出结果 #include <stdio.h>char * fun1() {char * str = "hello";return str; }char * ...

  2. 栈区,堆区,全局区,文字常量区,程序代码区详解(程序中不同类型数据所在区)

    一.预备知识-程序的内存分配     一个由C/C++编译的程序占用的内存分为以下几个部分     1.栈区(stack)-   由编译器自动分配释放   ,存放函数的参数值,局部变量的值等.其   ...

  3. c语言中全局变量内存,C语言——全局变量和局部变量在内存中的区别——及编译后的内存分区【栈-堆-全局存储区-文字常量区-程序代码区】...

    目录: 一:全局变量 二:局部变量 三:C语言经过编译之后将内存分为以下几个区域 (1)栈(stack) (2)堆(heap) (3)全局(静态)存储区 (4)文字常量区 (5)程序代码区 四:区别 ...

  4. 程序的内存分配模式(堆栈以及静态存储区,文字常量区,代码区)

    程序的内存分配模式 一个由 C/C++编译的程序占用的内存分为以下几个部分: 1.栈区( stack )-由编译器自动分配释放,存放函数的参数值,局部变量的值 等.其操作方式类似于数据结构中的栈. 2 ...

  5. C语言中字符串定义与文字常量区

    C语言中字符串定义与文字常量区 C语言的内存组织方式1>代码区,存放可执行代码2>全局存储区,存放所有全局变量和静态变量3>文字常量区,常量字符串4>堆区,malloc,new ...

  6. 老生常谈:文字常量区的那点事

    2019独角兽企业重金招聘Python工程师标准>>> 文字常量区,在之前的一篇关于堆栈的文章中有所提及,今天在重点说一下文字常量区,在该区内存放常量字符串,为什么这么做了,就是节省 ...

  7. C语言内存分配-附图详解,代码区、常量区、栈区、堆区.......

    文章目录 C语言程序的内存组成 变量以及数组开辟内存空间地址大小问题 C语言程序的内存组成 不管对于那种编程语言而言,内存管理都十分重要.对于C语言程序来说,所占用的内存主要有以下几个部分:代码区(所 ...

  8. C++栈内存与文字常量区

    先看看以下测试demo char str1[] = "abc"; char str2[] = "abc"; const char str3[] = " ...

  9. C/C++堆区、栈区、常量区、静态数据区、代码区详解

    转自:http://blog.csdn.net/hackerain/article/details/7953261 http://blog.csdn.net/firefly_2002/article/ ...

最新文章

  1. python opencv 旋转图片
  2. 2017软件工程第一次作业
  3. windows 生成 deploy key_推荐一个免费生成点线/方格/横线纸张的网站
  4. ubuntu 命令行命令历史记录存储在哪个文件夹
  5. SQL Server学习之路(五):“增删改查”之“改”
  6. Ocelot.JwtAuthorize:一个基于网关的Jwt验证包
  7. 1787: [Ahoi2008]Meet 紧急集合
  8. 用友政务知识管理平台_云创数字政务大数据平台,助力政务工作高效管理
  9. php.js 文件下载,使用JavaScript开始下载文件
  10. Linux 命令(50)—— date 命令
  11. phpcount数组报错_PHPExcel把导入的excel表格转换为数组,然后运行,浏览器什么也不显示,也不报错...
  12. SpringMvc类型转换器
  13. Java中的frontcolor_front的用法总结大全
  14. pythoneducoder苹果梨子煮水的功效_【苹果梨子煮水喝的功效】_苹果好处_作用-大众养生网...
  15. Android 9.0系统源码_SystemUI(二)StatusBar系统状态栏的创建流程
  16. 海信E8K和E8H区别对比哪个好
  17. TestBird成为全球最大手游测试平台
  18. C语言合法标识符(含知识点)
  19. 两个向量组线性相关是不是也能说成两个向量组等价 向量组等价 线性相关 向量组等价和矩阵等价的区别
  20. 多光谱(RGB-T)语义分割2019-RTFNet总结

热门文章

  1. java异常深入理解与提升(含面试题)
  2. 什么是EFLOPS?
  3. 基于Java+MySQL实现(图形界面)NBA 数据分析系统【100010135】
  4. Redis(九):Redis的主从同步
  5. get请求中文传参乱码问题解决汇总终极版
  6. leetcode 25. K个一组反转链表
  7. 【MATLAB统计分析与应用100例】案例019:matlab读取Excel数据,进行K均值聚类分析
  8. 1125. 牛的旅行
  9. C2C平台退换货逆向寄件服务,快递鸟“上门取件“解决方案
  10. 我用python玩炉石传说(2)-----炉石卡牌套牌爬取器及自动分析卡牌相关度