文档章节

学点 C 语言(34): 函数 - 关于变量(auto、static、register、extern、volatile、restrict)

涂孟超
 涂孟超
发布于 2014/09/26 15:34
字数 1064
阅读 1
收藏 0
点赞 0
评论 0

1. 局部变量:

局部变量也叫自动变量, 它声明在函数开始, 生存于栈, 它的生命随着函数返回而结束.
#include <stdio.h>

int main(void)
{
    auto int i = 9; /* 声明局部变量的关键字是 auto; 因可以省略, 几乎没人使用 */   

    printf("%d\n", i);  
    getchar();
    return 0;
}

 
 
 
 
 

 

 

  

2. 全局变量:

全局变量声明在函数体外, 一般应在函数前; 每个函数都可以使用它, 不过全局变量应尽量少用.
#include <stdio.h>

void add(void);
void mul(void);

int gi = 3; /* 全局变量 */

int main(void)
{    
    printf("%d\n", gi);  /* 3  */

    add();
    printf("%d\n", gi);  /* 5  */

    mul();
    printf("%d\n", gi);  /* 10 */
      
    getchar();
    return 0;
}

void add(void) {
    gi += 2;
}

void mul(void) {
    gi *= 2;
}

 
 
 
 
 

 

 

  

全局变量会被初始化为空, 而局部变量在没有赋值前是一个垃圾值:
#include <stdio.h>

int gi; /* 全局变量 */

int main(void)
{
    int i; /* 句柄变量 */
    
    printf("%d, %d\n", gi, i);
      
    getchar();
    return 0;
}

 
 
 
 
 

 

 

  

当全局变量与局部变量重名时, 使用的是局部变量:
#include <stdio.h>

int a = 111, b = 222;

int main(void)
{
    int a = 123;
    printf("%d,%d\n", a, b); /* 123,222*/

    getchar();    
    return 0;
}

 
 
 
 
 

 

 

  

3. static 关键字:

用 static 关键字修饰的局部变量是静态局部变量;
静态局部变量存值如同全局变量, 区别在于它只属于拥有它的函数; 它也会被初始化为空.
#include <stdio.h>

void fun1(void);
void fun2(void);

int main(void)
{    
    int i;
    
    for (i = 0; i < 10; i++) fun1();
    printf("---\n");
    for (i = 0; i < 10; i++) fun2();
    
    getchar();
    return 0;
}

void fun1(void) {
    int n = 0;        /* 一般的局部变量 */
    printf("%d\n", n++);
}

void fun2(void) {
    static int n;     /* 静态局部变量; 会被初始化为空 */
    printf("%d\n", n++);
}

 
 
 
 
 

 

 

  

用 static 关键字修饰的全局变量是静态全局变量; 静态全局变量只能用于定义它的单元.
//譬如在 File1.c 里面定义了:
static int num = 99;  /* 去掉前面的 static 其他单元才可以使用 */

//在 File2.c 里使用:
#include <stdio.h>

extern int num;

int main(void)
{    
    printf("%d\n", num);
 
    getchar();
    return 0;
}

 
 
 
 
 

 

 

  

用静态变量记录函数被调用的次数:
#include <stdio.h>

int fun(void);

int main(void)
{    
    int i;
    for (i = 0; i < 10; i++) {
        printf("函数被调用了 %2d 次;\n", fun());
    }     
    getchar();
    return 0;
}

int fun(void) {
    static int n;
    return ++n;
}

 
 
 
 
 

 

 

  

4. 寄存器变量(register):

书上说寄存器变量会尽量把变量放到寄存器(而不是栈或堆), 从而加快存取速度, 我试了一下, 效果一般般.
#include <stdio.h>
#include <time.h>

#define TIME 1000000000

int m, n = TIME; /* 全局变量 */

int main(void)
{   
    time_t start, stop;

    register int a, b = TIME; /* 寄存器变量 */
    int x, y = TIME;          /* 一般变量   */
    
    time(&start);
    for (a = 0; a < b; a++);
    time(&stop);
    printf("寄存器变量用时: %d 秒\n", stop - start);

    time(&start);
    for (x = 0; x < y; x++);
    time(&stop);
    printf("一般变量用时: %d 秒\n", stop - start);

    time(&start);
    for (m = 0; m < n; m++);
    time(&stop);
    printf("全局变量用时: %d 秒\n", stop - start);
 
    getchar();
    return 0;
}

 
 
 
 
 

 

 

  

4. extern 关键字:

使用外部全局变量应该用 extern 重新声明一下;
如果不使用 extern, 将是重新定义;
在链接阶段, 同一程序中不同单元的全局变量是共用的所以不能重新定义;
本例为了省事并没有涉及另一个文件, 只是把变量放在文件尾模拟了一下.

另外, extern 主要还是用于函数.
#include <stdio.h>

extern int g1;

int main(void)
{    
    extern int g2;

    printf("%d,%d\n", g1,g2);  
    getchar();
    return 0;
}

int g1 = 77;
int g2 = 88;

 
 
 
 
 

 

 

  

5. volatile 关键字:

程序在使用变量时, 特别是连续多次使用变量时, 一般是载入寄存器, 直接从寄存器存取, 之后再还回内存;
但如果此变量在返回内存时, 假如内存中的值已经改变了(从外部修改了)怎么办?
为了避免这种情况的发生, 可以用 volatile 说明此变量, 以保证变量的每次使用都是直接从内存存取.
但这样肯定会影响效率, 幸好它并不常用.

另外: 如果 const volatile 同时使用, 这表示此变量只接受外部的修改.
#include <stdio.h>

volatile int num = 123;

int main(void)
{    
    printf("%d\n", num);
    getchar();
    return 0;
}

 
 
 
 
 

 

 

  

6. restrict 关键字:

restrict 有点和 volatile 相反; 不过 restrict 只是对指针.
好像 C++Builder 2009 并不支持它, 暂时无法测试.

本文转载自:http://www.cnblogs.com/del/archive/2008/12/04/1347305.html

共有 人打赏支持
涂孟超
粉丝 12
博文 2011
码字总数 14107
作品 0
深圳
程序员
Storage duration(C++学习)

Storage duration Storage duration,顾名思义,存储空间本身的持续时间。它应当不小于其所包含对象的生存周期(object lifetime)。 标准原文 和 C99,C++03比,新标准增加了一个thread相关的...

晨曦之光
2012/05/08
82
0
2675字带你进阶C语言中的关键字.md

C语言进阶之C语言关键字 关键字总结.png 基本数据类型 1.数据类型 数据类型可以理解为固定内存大小的别名(例如,在C语言中int数据类型代表了4个字节的内存) 数据类型是可以创建变量的模板...

PcDack
2017/12/03
0
0
C语言的变量属性

在定义变量的时候可以加上属性关键字 1)auto auto是C语言中,局部变量的默认属性 auto表明将被修饰的变量存储于栈上 编译器默认所有的局部变量都是auto的 2)register 1.register关键字指明...

ElleryQueen
2017/11/20
0
0
[数据结构]-散列表(哈希表)

在这里没有新的原创性的东西。该部分内容主要取材于《软件设计师教程》部分的内容。 我想强调一种数据结构,散列表。它是基于快速存取的角度设计的,也是一种典型的“空间换时间”的做法。顾...

hoodlum1980
2008/02/18
0
0
C语言再学习--关键字

C语言一共有32个关键字,如下表所示: 关键字 说明 auto 声明自动变量 short 声明短整型变量或函数 int 声明整型变量或函数 long 声明长整型变量或函数 float 声明浮点型变量或函数 double 声...

qq_29350001
2016/11/03
0
0
C++ 内存模型和名称空间

一、存储的连续性 连续性:通俗来说,就是关于变量的创建与取消的管理方式,有的是自动创建自动释放,有的需要手动处理,有的变量产生后在程序运行时一直存在等。。。 数据的存储有不同的特征...

CWY_007
2017/04/02
0
0
C语言的四种存储类型(auto register static extern)

注意:很多情况下我们会误用 c 的 关键字。 下面我们详细讲讲 C 的存储类型(Storage Classes) auto 是所有局部变量默认的存储类。 上述定义了两个带有相同存储类的变量, 只能用在函数内,...

傅易
2016/12/12
18
0
C 存储类

存储类定义 C 程序中变量/函数的范围(可见性)和生命周期。这些说明符放置在它们所修饰的类型之前。下面列出 C 程序中可用的存储类: auto register static extern auto 存储类 auto 存储类...

不最醉不龟归
2016/10/05
13
0
C++变量的存储说明符和cv-限定符

在C++中创建变量时,前面有时会有一些修饰符,这里总结一下。 大体分为两个类别:存储说明符和cv-限定符。 存储说明符 存储说明符有下面这些: auto register static extern mutable auto修饰...

Cloudox_
2017/12/02
0
0
小朋友学Python(10):C/C++/Java/Python的关键字

一、C语言关键字 C语言关键字有32个 auto break case char const continue default do double else enum extern float for goto if int long register return short signed sizeof static s......

翡翠森林Z
2017/12/28
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

Android 复制和粘贴功能

做了一回搬运工,原文地址:https://blog.csdn.net/kennethyo/article/details/76602765 Android 复制和粘贴功能,需要调用系统服务ClipboardManager来实现。 ClipboardManager mClipboardM...

她叫我小渝
26分钟前
0
0
拦截SQLSERVER的SSL加密通道替换传输过程中的用户名密码实现运维审计(一)

工作准备 •一台SQLSERVER 2005/SQLSERVER 2008服务 •SQLSERVER jdbc驱动程序 •Java开发环境eclipse + jdk1.8 •java反编译工具JD-Core 反编译JDBC分析SQLSERVER客户端与服务器通信原理 SQ...

紅顏為君笑
42分钟前
4
0
jQuery零基础入门——(六)修改DOM结构

《jQuery零基础入门》系列博文是在廖雪峰老师的博文基础上,可能补充了个人的理解和日常遇到的点,用我的理解表述出来,主干出处来自廖雪峰老师的技术分享。 在《零基础入门JavaScript》的时...

JandenMa
59分钟前
0
0
linux mint 1.9 qq 安装

转: https://www.jianshu.com/p/cdc3d03c144d 1. 下载 qq 轻聊版,可在百度搜索后下载 QQ7.9Light.exe 2. 去wine的官网(https://wiki.winehq.org/Ubuntu) 安装 wine . 提醒网页可以切换成中...

Canaan_
今天
0
0
PHP后台运行命令并管理运行程序

php后台运行命令并管理后台运行程序 class ProcessModel{ private $pid; private $command; private $resultToFile = ''; public function __construct($cl=false){......

colin_86
今天
1
0
数据结构与算法4

在此程序中,HighArray类中的find()方法用数据项的值作为参数传递,它的返回值决定是否找到此数据项。 insert()方法向数组下一个空位置放置一个新的数据项。一个名为nElems的字段跟踪记录着...

沉迷于编程的小菜菜
今天
1
1
fiddler安装和基本使用以及代理设置

项目需求 由于开发过程中客户端和服务器数据交互非常频繁,有时候服务端需要知道客户端调用接口传了哪些参数过来,这个时候就需要一个工具可以监听这些接口请求参数,已经接口的响应的数据,这种...

银装素裹
今天
0
0
Python分析《我不是药神》豆瓣评论

读取 Mongo 中的短评数据,进行中文分词 对分词结果取 Top50 生成词云 生成词云效果 看来网上关于 我不是药神 vs 达拉斯 的争论很热啊。关于词频统计就这些,代码中也会完成一些其它的分析任...

猫咪编程
今天
0
0
虚拟机怎么安装vmware tools

https://blog.csdn.net/tjcwt2011/article/details/72638977

AndyZhouX
昨天
1
0
There is no session with id[xxx]

参考网页 https://blog.csdn.net/caimengyuan/article/details/52526765 报错 2018-07-19 23:04:35,330 [http-nio-1008-exec-8] DEBUG [org.apache.shiro.web.servlet.SimpleCookie] - Found......

karma123
昨天
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部