C高阶3:变量分类

1. 本地变量/局部变量

1.1 本地变量/局部变量是什么?

在大括号内定义的变量就是本地变量/局部变量。

1.2 本地变量/局部变量有什么特点?

  1. 本地变量是定义在代码块内的,可以定义在函数的块内,可以定义在语句的块内。
for(int i=0;i<10;++i){
    printf("%d ",i);
}
printf("%d ",i);

可以定义在一个随意的大括弧里面。

{
    int n = 0;
    printf("%d ",n);
}
printf("%d ",n);
  1. 程序进入块前,内部变量不存在,离开时失效
  2. 块外定义的变量,块内仍然有效。

函数的每次运行,都会产生一个独立的变量空间,在这个空间中的变量,是函数这次运行独有的。

  • 定义在函数内部的变量就是本地变量
  • 参数也是本地变量

1.3 本地变量/局部变量初始化

  1. 本地变量不会默认初始化
  2. 参数在进入函数时被初始化。

本地变量/局部变量的生存期和作用域都是在大括号内。

2. 全局变量

2.1 全局变量是什么?

定义在函数外面的变量称为全局变量

int n;
int main(){
    int m;
    printf("n=%d\m=%d\n",n,m);
}

2.2 全局变量有什么特点?

全局变量有全局的生存周期和作用域。

  1. 不属于任何函数。
  2. 所有函数内部都可以使用。
int n;
int func(){
    printf("in func n = %d\n",n);
    // n = n*2;
}
int main(){
    scanf("%d",&n);
    func();
    printf("in main n = %d\n",n);
}

2.3 全局变量初始化

  1. 没有初始化的全局变量会自动初始化为0
  2. 只能用编译时刻已知的值初始化全局变量。
  3. 初始化发生在main()前。
int n = 2;
int m = n;
double  s = sqrt(n); 
int main(){
    printf("n = %d,m = %d,s = %f",n,m,s);
}

2.4 同名隐藏

如果函数内部存在与全局变量同名的变量,则全局变量被隐藏。

int n = 10;
int main(){
    int n = 1;
    printf("n = %d\n",n);
}

3. 全局静态变量

3.1 全局静态变量是什么?

在全局变量前加上关键字static

static int n;
int main(){
    int m;
    printf("n=%d\m=%d\n",n,m);
}

3.2 全局变量与全局静态变量区别

  1. 若程序由一个源文件构成时,全局变量与全局静态变量没有区别。
  2. 若程序由多个源文件构成时,全局变量与全局静态变量不同:全局静态变量使得该变量成为定义该变量的源文件所独享,即:全局静态变量对组成该程序的其它源文件是无效的。
  3. 具有外部链接的静态,可以在所有源文件里调用,除了本文件,其他文件可以通过extern的方式引用。

4. 本地静态变量

4.1 静态本地变量是什么?

在本地变量定义时加上static变成静态本地变量。

4.2 静态本地变量有什么特点?

当函数离开时,静态本地变量会继续存在并保存其值。

int inc(){
    static int n = 1;
    n = n + 1;
    return n;
}
int main(){
    printf("%d\n",inc());
    printf("%d\n",inc());
    printf("%d\n",inc());
}

静态本地变量的初始化在第一次进入函数时执行,以后进入函数会保持离开的值。
静态本地变量是特殊的全局变量,具有全局生存周期和局部作用域。

5. 总结

5.1 变量的作用域和生命期

  • 作用域
    变量或函数在运行时候的 有效作用范围 。
  • 生命期
    变量或函数在运行时候的没被销毁回收的存活时间。
No. 分类 作用域 生命期
1 局部变量 所在代码块内 所在函数结束
2 全局变量 所有文件内 程序执行结束
3 静态局部变量 所在代码块内 程序执行结束
4 静态全局变量 当前文件内 程序执行结束
5 普通函数 所有文件内 -
6 静态函数 当前文件内 -

6. static关键字小结:

static在C语言里面既可以修饰变量,也可以修饰函数。

  • static变量:

    1. 静态局部变量:在函数中定义的,生命周期是整个源程序,但是作用域和局部变量没区别。
      只能在定义这个变量的函数范围内使用,而且只在第一次进入这个函数时候被初始化,之后的初始化会跳过,并保留原来的值。退出这个函数后,尽管这个变量还在,但是已经不能使用了。

    2. 静态全局变量:全局变量本身就是静态存储的,但是静态全局变量和非静态全局变量又有区别:

      1. 全局变量:变量的作用域是整个源程序,其他源文件也可以使用,生命周期整个源程序。
      2. 静态全局变量:变量的作用域范围被限制在当前文件内,其他源文件不可使用,生命周期整个源程序。
  • static函数(内部函数):
    只能被当前文件内的其他函数调用,不能被其他文件内的函数调用,主要是区别非静态函数(外部函数)。

不对外公开的函数和全局变量
在函数前面加上static就使它成为只能所在编译文件中使用的函数。
在全局变量前加上static使它成为只能所在编译文件中使用的全局变量。

7. 最佳实践

7.1 不要返回本地变量的指针

  1. 返回本地变量的地址是危险的。
  2. 返回全局变量或静态本地变量的地址是安全的。
  3. 返回函数内的动态内存是安全的,但注意要记得释放。
  4. 最好的做法是返回传入的指针。

7.2 慎用静态变量

不要使用全局变量在函数间传递参数和结果。
尽量避免使用全局变量。
使用全局变量和静态本地变量的函数是不可重入的,是线程不安全的。

  • 如何解决返回局部数据的问题?
#include <stdio.h>
#include <stdlib.h>
void print_array(int arr[],int n){
    for(int i=0;i<n;++i){
        printf("%d ",arr[i]);
    }
    printf("\n");
}
int* scanf_array(int* n){
    scanf("%d",n);
    int* arr = (int*)malloc(*n*sizeof(int));
    for(int i=0;i<*n;++i){
        scanf("%d",&arr[i]);
    }
    return arr;
}
int main(){
    int n;
    int *arr = scanf_array(&n);
    print_array(arr,n);
    free(arr);
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 227,224评论 6 529
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 97,916评论 3 413
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 175,014评论 0 373
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 62,466评论 1 308
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 71,245评论 6 405
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 54,795评论 1 320
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 42,869评论 3 440
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 42,010评论 0 285
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 48,524评论 1 331
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 40,487评论 3 354
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 42,634评论 1 366
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 38,173评论 5 355
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 43,884评论 3 345
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 34,282评论 0 25
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 35,541评论 1 281
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 51,236评论 3 388
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 47,623评论 2 370

推荐阅读更多精彩内容

  • 昨晚女儿去上英语补习课,今天早上自己一个人去补习数学,这个地方上学期女儿去了一个月,这次是女儿自己说想去补习,并自...
    桂E初六阅读 114评论 0 1
  • 昨天下午,女儿学校,六一儿童节表演节目。四点钟开始,我关闭店门,和老公一起去欣赏孩子们演出。其实,我们可以一个人看...
    玉妮阅读 272评论 11 7
  • 夏天这么燥热,消暑纳凉去哪儿?当然是游湖啊!GO!GO!GO! 小伙伴们要问青海湖排第几?当然是第一啊!是不是有种...
    甲乙旅行菌阅读 512评论 0 3
  • 今天周日,也是我的工作日,给孩子们上课。每周这样,周而复始。 今天,按照我的惯例给孩子们讲完内容,进行当堂课内容的...
    佟小扣阅读 405评论 6 1