看c专家编程,有说存储类型一直不太清楚。看到一篇文章讲解c的存储类型,讲解了c语言中的各种变量的存储类型,而且是从进程、内存的角度讲解的,以前从没有这样理解过,觉得挺有用的,在这里转载过来。

首先要来理解一下可执行文件加载进内存后形成的进程在内存中的结构,如下图:

代码区:存放CPU执行的机器指令,代码区是可共享,并且是只读的。

数据区:存放已初始化的全局变量、静态变量(全局和局部)、常量数据。

BBS区:存放的是未初始化的全局变量和静态变量。

栈区:由编译器自动分配释放,存放函数的参数值、返回值和局部变量,在程序运行过程中实时分配和释放,栈区由操作系统自动管理,无须程序员手动管理。

堆区:堆是由malloc()函数分配的内存块,使用free()函数来释放内存,堆的申请释放工作由程序员控制,容易产生内存泄漏。

c语言中的存储类型有auto, extern, register, static 这四种,存储类型说明了该变量要在进程的哪一个段中分配内存空间,可以为变量分配内存存储空间的有数据区、BBS区、栈区、堆区。下面来一一举例看一下这几个存储类型:

1. auto存储类型

auto只能用来标识局部变量的存储类型,对于局部变量,auto是默认的存储类型,不需要显示的指定。因此,auto标识的变量存储在栈区中。示例如下:

[cpp] view
plain
copy

 
  1. #include <stdio.h>
  2. int main(void)
  3. {
  4. auto int i=1; //显示指定变量的存储类型
  5. int j=2;
  6. printf("i=%d\tj=%d\n",i,j);
  7. return 0;
  8. }

2. extern存储类型

extern用来声明在当前文件中引用在当前项目中的其它文件中定义的全局变量。如果全局变量未被初始化,那么将被存在BBS区中,且在编译时,自动将其值赋值为0,如果已经被初始化,那么就被存在数据区中。全局变量,不管是否被初始化,其生命周期都是整个程序运行过程中,为了节省内存空间,在当前文件中使用extern来声明其它文件中定义的全局变量时,就不会再为其分配内存空间。

示例如下:

[cpp] view
plain
copy

 
  1. #include <stdio.h>
  2. int i=5; //定义全局变量,并初始化
  3. void test(void)
  4. {
  5. printf("in subfunction i=%d\n",i);
  6. }
[cpp] view
plain
copy

 
  1. #include <stdio.h>
  2. extern i; //声明引用全局变量i
  3. int main(void)
  4. {
  5. printf("in main i=%d\n",i);
  6. test();
  7. return 0;
  8. }
[plain] view
plain
copy

 
  1. $ gcc -o test test.c file.c  #编译连接
  2. $ ./test  #运行
[plain] view
plain
copy

 
  1. 结果:
  2. in main i=5
  3. in subfunction i=5

3. register存储类型

声明为register的变量在由内存调入到CPU寄存器后,则常驻在CPU的寄存器中,因此访问register变量将在很大程度上提高效率,因为省去了变量由内存调入到寄存器过程中的好几个指令周期。如下示例:

[cpp] view
plain
copy

 
  1. #include <stdio.h>
  2. int main(void)
  3. {
  4. register int i,sum=0;
  5. for(i=0;i<10;i++)
  6. sum=sum+1;
  7. printf("%d\n",sum);
  8. return 0;
  9. }

4. static存储类型

被声明为静态类型的变量,无论是全局的还是局部的,都存储在数据区中,其生命周期为整个程序,如果是静态局部变量,其作用域为一对{}内,如果是静态全局变量,其作用域为当前文件。静态变量如果没有被初始化,则自动初始化为0。静态变量只能够初始化一次。示例如下:

[cpp] view
plain
copy

 
  1. #include <stdio.h>
  2. int sum(int a)
  3. {
  4. auto int c=0;
  5. static int b=5;
  6. c++;
  7. b++;
  8. printf("a=%d,\tc=%d,\tb=%d\t",a,c,b);
  9. return (a+b+c);
  10. }
  11. int main()
  12. {
  13. int i;
  14. int a=2;
  15. for(i=0;i<5;i++)
  16. printf("sum(a)=%d\n",sum(a));
  17. return 0;
  18. }
[plain] view
plain
copy

 
  1. $ gcc -o test test.c
  2. $ ./test
  3. a=2,    c=1,    b=6 sum(a)=9
  4. a=2,    c=1,    b=7 sum(a)=10
  5. a=2,    c=1,    b=8 sum(a)=11
  6. a=2,    c=1,    b=9 sum(a)=12
  7. a=2,    c=1,    b=10    sum(a)=13

6. 字符串常量

字符串常量存储在数据区中,其生存期为整个程序运行时间,但作用域为当前文件,示例如下:

[cpp] view
plain
copy

 
  1. #include <stdio.h>
  2. char *a="hello";
  3. void test()
  4. {
  5. char *c="hello";
  6. if(a==c)
  7. printf("yes,a==c\n");
  8. else
  9. printf("no,a!=c\n");
  10. }
  11. int main()
  12. {
  13. char *b="hello";
  14. char *d="hello2";
  15. if(a==b)
  16. printf("yes,a==b\n");
  17. else
  18. printf("no,a!=b\n");
  19. test();
  20. if(a==d)
  21. printf("yes,a==d\n");
  22. else
  23. printf("no,a!=d\n");
  24. return 0;
  25. }
[plain] view
plain
copy

 
  1. $ gcc -o test test.c
  2. $ ./test
  3. yes,a==b
  4. yes,a==c
  5. no,a!=d

总结如下表:

 

C语言存储类型的更多相关文章

  1. C语言存储类型及各存储类型作用域和生存域比较

    c语言中的存储类型有`auto`, `extern`, `register`,`static` 这四种,存储类型说明了该变量要在进程的哪一个段中分配内存空间,可以为变量分配内存存储空间的有数据区.BB ...

  2. 【C语言学习】存储类型

    C语言中的存储类型主要有四种:auto.static.extern.register ★auto存储类型 默认的存储类型.在C语言中,假设忽略了变量的存储类型,那么编译器就会自己主动默认为auto型 ...

  3. C语言中标识符的作用域、命名空间、链接属性、生命周期、存储类型

    Technorati 标签: C,标识符,作用域,命名空间,链接属性,生命周期,存储类型,scope,name space,linkage,storage durations,lifetime 无论学 ...

  4. C语言中变量的存储类型

    在C语言中,对变量的存储类型说明有以下四种: auto 自动变量register   寄存器变量extern 外部变量static   静态变量 自动变量和寄存器变量属于动态存储方式,外部变量和静态变 ...

  5. C语言中的作用域,链接属性和存储类型

    作用域 当变量在程序的某个部分被声明的时候,他只有在程序的一定渔区才能被访问,编译器可以确认4种不同类型的作用域:文件作用域,函数作用域,代码块作用域和原型作用域 1.代码块作用域:位于一对花括号之间 ...

  6. c语言的数据类型,运算符,存储类型

    [1词法符号]1. 关键字:32个1) 存储类型:决定(设备)变量的存储位置auto(自动型).extern(外部引用) static(静态型) register(寄存器类型)2) 数据类型:决定设备 ...

  7. C语言中【变量】的存储类型共有4种类型

    在C语言中,对变量的存储类型说明有以下四种:   auto          自动变量 (动态存储) register     寄存器变量(动态存储) extern       外部变量(静态存储) ...

  8. C语言作用域、链接属性和存储类型

    C/C++中作用域详解 作用域 编译器可以确认的4种作用域-代码块作用域.文件作用域.函数作用域和原型作用域,一般来说,标识符(包括变量名和函数名)声明的位置决定它的作用域. (1)代码块作用域 一对 ...

  9. C和指针 3.9作用域、存储类型示例

    ; extern int b; static int c; int d( int e ) { ; register int b; ; extern int a; ... { int e; int a; ...

随机推荐

  1. poj-1151矩形面积并-线段树

    title: poj-1151矩形面积并-线段树 date: 2018-10-30 22:35:11 tags: acm 刷题 categoties: ACM-线段树 概述 线段树问题里的另一个问题, ...

  2. Java 中的异常处理机制

    生活中的异常:  不能够完整而顺利的完成一些工作 根据不同的异常进行相应的处理,而不会就此终端我们的生活 引出:  异常处理: 方式:  1.选择结构(逻辑判断)避免 demo:if逻辑处理异常 im ...

  3. Mac 上自带TFTP Server 软件的使用

    搬瓦工搭建SS教程 1.TFTP协议 简单文件传输协议Trivial File Transfer Protocol (TFTP)是一个基于UDP协议的简单的.低开销的文件传输协议,允许客户端get或者 ...

  4. Android Actionbar Tab 导航模式

    Android Actionbar Tab 下图中,红色矩形圈起来的就是我们 ActionBar Tab,下面我们将一步一步的实现下图中的效果. 初次尝试 package com.example.it ...

  5. Django小知识点整理

    一.Django中Choices字段显示中文的两种方式 1.get_xxxx_display():这种方式只能针对对象来使用 {% for row in server_list %} <li&g ...

  6. http常见请求头与响应头

    1.HTTP常见的请求头 If-Modified-Since:把浏览器端缓存页面的最后修改时间发送到服务器去,服务器会把这个时间与服务器上实际文件的最后修改时间进行对比.如果时间一致,那么返回304, ...

  7. apt-get出现无法定位安装包问题解决

    这个问题出现在sources.list上 编辑/etc/apt/sources.list下的文件 找到检查你的存储库是否正确 你可以在以下页面找到不同版本 Kali Linux 的存储库:http:/ ...

  8. 20162327WJH第三次实验——查找与排序2

    20162327WJH第三次实验--查找与排序2 实 验 报 告 课程:程序设计与数据结构 班级: 1623 姓名: 王旌含 学号:20162327 成绩: 指导教师:娄嘉鹏 王志强 实验日期:11月 ...

  9. poj 3164

    朱刘算法 步骤: 1.计算出每个点边权最小的边的权(如果除根以外有其他的点没有入边,则不存在最小树形图),并记下边的另一个端点(称其为这个点的前趋) 2.沿着每个点向上走,如果在走到根或环上的点之前, ...

  10. 20172333 2017-2018-2 《Java程序设计》第6周学习总结

    20172333 2017-2018-2 <Java程序设计>第6周学习总结 教材学习内容 1.数组的基本用法,如数组的定义:int[该数组类型] name = new int[X]X为数 ...