一、全局变量

  1. 定义在函数外面的变量是全局变量
  2. 全局变量具有全局的生存期和作用域
  3. 它们与任何函数无关,在任何函数内部都可以使用它们
#include <stdio.h>

int f(void);

// 全局变量
int gALL = 12; int main(int argc, char const *argv[])
{
printf("in %s gALL=%d\n", __func__,gALL);
f(); printf("agn in %s gALL=%d\n", __func__,gALL); return 0;
} int f(void)
{
printf("in %s gALL=%d\n", __func__,gALL);
gALL += 8;
printf("agn in %s gALL=%d\n", __func__,gALL);
return gALL;
} // in main gALL=12
// in f gALL=12
// agn in f gALL=20
// agn in main gALL=20

二、全局变量初始化

  1. 没有做初始化的全局变量会得到0值
  2. 指针会得到NULL值
  3. 只能用编译时刻已知的值来初始化全局变量
  4. 它们的初始化发生在main函数之前

三、被隐藏的全局变量

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

#include <stdio.h>

int f(void);

// 全局变量
int gALL = 12; int main(int argc, char const *argv[])
{
printf("in %s gALL=%d\n", __func__,gALL);
f(); printf("agn in %s gALL=%d\n", __func__,gALL); return 0;
} int f(void)
{
// 这里定义一个名字相同的变量,那么全局的就被隐藏了
int gALL = 1;
printf("in %s gALL=%d\n", __func__,gALL);
gALL += 8;
printf("agn in %s gALL=%d\n", __func__,gALL);
return gALL;
}
// in main gALL=12
// in f gALL=1
// agn in f gALL=9
// agn in main gALL=12

四、静态本地变量

  1. 在本地变量定义时加上static修饰符就成为静态本地变量
  2. 当函数离开的时候,静态本地变量会继续存在并保持其值
  3. 静态本地变量的初始化只会在第一次进入这个函数时做,以后进入函数时会保持上次离开的值
#include <stdio.h>

int f(void);

int main(int argc, char const *argv[])
{
f();
f(); return 0;
} int f(void)
{
static int all = 1;
printf("in %s all=%d\n", __func__,all);
all += 9;
printf("agn in %s all=%d\n", __func__,all);
return all;
}
// in f all=1
// agn in f all=10
// in f all=10
// agn in f all=19

注意事项

  1. 静态本地变量实际上是特殊的全局变量
  2. 它们位于相同的内存区域
  3. 静态本地变量具有全局的生存期,函数内的局部作用域
  4. static在这里的意思就是局部作用域(本地可以访问)

五、后记:返回指针的函数

  1. 返回本地变量的地址是危险的
  2. 返回全局变量或静态本地变量的地址是安全的
  3. 返回在函数内malloc的内存是安全的,但是容易造成问题
  4. 最好的做法是返回传入的指针

下面的写法就是很危险的

#include <stdio.h>

int* f(void);
void g(void); int main(int argc, char const *argv[])
{
int *p = f();
printf("*p = %d\n", *p);
g();
printf("*p = %d\n", *p); return 0;
} int* f(void)
{
int i = 12; // 返回本地变量的地址是危险的
return &i;
} void g(void)
{
int k = 24;
printf("k = %d\n", k);
} // *p = 12
// k = 24
// *p = 24

tips

  1. 不要使用全局变量来在函数间传递参数和结果
  2. 尽量避免使用全局变量
  3. 使用全局变量和静态本地变量的函数是线程不安全的

C语言入门-全局变量的更多相关文章

  1. 《Ruby语言入门教程v1.0》学习笔记-01

    <Ruby语言入门教程v1.0> 编著:张开川 邮箱:kaichuan_zhang@126.com 想要学习ruby是因为公司的自动化测试使用到了ruby语言,但是公司关于ruby只给了一 ...

  2. c语言入门这一篇就够了-学习笔记(一万字)

    内容来自慕课网,个人学习笔记.加上了mtianyan标签标记知识点. C语言入门 -> Linux C语言编程基本原理与实践 -> Linux C语言指针与内存 -> Linux C ...

  3. Go 语言入门(一)基础语法

    写在前面 在学习 Go 语言之前,我自己是有一定的 Java 和 C++ 基础的,这篇文章主要是基于A tour of Go编写的,主要是希望记录一下自己的学习历程,加深自己的理解 Go 语言入门(一 ...

  4. 【Introduction】R语言入门关键小结

    写在前面:本博客为本人原创,严禁任何形式的转载!本博客只允许放在博客园(.cnblogs.com),如果您在其他网站看到这篇博文,请通过下面这个唯一的合法链接转到原文! 本博客全网唯一合法URL:ht ...

  5. C语言入门基础整理

    学习计算机技术,C语言可以说是必备的,他已经成为现在计算机行业人学习必备的,而且应用也是十分的广泛,今天就来看看拥有几年c语言工作经验的大神整理的C语言入门基础知识,没有学不会,只有不肯学. 结构化程 ...

  6. C/C++编程笔记:C语言入门知识点(三),请收藏C语言最全笔记!

    今天我们继续来学习C语言的入门知识点,第一课:C/C++编程笔记:C语言入门知识点(二),请收藏C语言最全笔记! 21. 输入 & 输出 当我们提到输入时,这意味着要向程序填充一些数据.输入可 ...

  7. 《JavaScript语言入门教程》记录整理:运算符、语法和标准库

    目录 运算符 算数运算符 比较运算符 布尔运算符 二进制位运算符 void和逗号运算符 运算顺序 语法 数据类型的转换 错误处理机制 编程风格 console对象和控制台 标准库 Object对象 属 ...

  8. 《JavaScript语言入门教程》记录整理:面向对象

    目录 面向对象编程 实例对象与 new 命令 this关键字 对象的继承 Object对象的方法 严格模式(strict mode) 本系列基于阮一峰老师的<JavaScrip语言入门教程> ...

  9. 踢爆IT劣书出版黑幕——由清华大学出版社之《C语言入门很简单》想到的(1)

    1.前言与作者 首先声明,我是由于非常偶然的机会获得<C语言入门很简单>这本书的,绝对不是买的.买这种书实在丢不起那人. 去年这书刚出版时,在CU论坛举行试读推广,我当时随口说了几句(没说 ...

随机推荐

  1. IPhone下json的解析 NSJSONSerialization

    JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式. 易于人阅读和编写.同时也易于机器解析和生成. 它基于JavaScript Programming Lan ...

  2. goal

    线段树进阶,主席树,莫队,相似kmp,悬线,单调栈,单调队列,ac自动机,后缀数组,后缀自动机 图论:最短路,差分约束,二分图,网络流,连通分量 不学图论了我太难了   三分找,单调增+max+单调减 ...

  3. Zabbix 监控MySQL、Apache、Nginx应用监控

    zabbix对第三方应用软件的监控,主要有两个工作难点,一个是编写自定义监控脚本,另一个是在编写模板并导入zabbix web中,编写脚本这个要根据 监控需求定制即可,而编写模板文件有些难度,不过网上 ...

  4. isensor app kit 之 CF5642V2 OV5642 测试总结

    . 总结; 使用官哥的cf5642c-v2时,需要将isensor app kit 上的iic上拉电阻去掉,否则可能导致寄存器初始化不成功,去掉即可,使用柴草电子的模组则不需要.

  5. Git下载安装及github基本操作

    Windows下Git下载 官网提供的Git下载地址: 官网下载地址,一般直接从官网下载会出现无反应等情况,这里提供windows32和64位版本的百度网盘资源:windows下的Git下载地址.有需 ...

  6. Day 09 函数

    目录 函数 函数的基本概念 为何使用函数 定义函数 什么是参数(形参,parameter) 定义函数的三种形式 无参函数 有参函数 空函数 函数的参数 形参和实参(parameter & ar ...

  7. 从零开始入门 K8s | etcd 性能优化实践

    作者 | 陈星宇(宇慕)  阿里云基础技术中台技术专家 本文整理自<CNCF x Alibaba 云原生技术公开课>第 17 讲. 导读:etcd 是容器云平台用于存储关键元信息的组件.阿 ...

  8. 十年Java程序员-带你走进Java虚拟机-类加载机制

    类的生命周期 1.加载 将.class文件从磁盘读到内存 2.连接 2.1 验证 验证字节码文件的正确性 2.2 准备 给类的静态变量分配内存,并赋予默认值 2.3 解析 类装载器装入类所引用的其它所 ...

  9. haproxy 在centos上cannot bind 端口的问题

    setsebool -P haproxy_connect_any=1 要不把selinux干掉也行

  10. ACM/ICPC 2018亚洲区预选赛北京赛站网络赛 D 80 Days (线段树查询最小值)

    题目4 : 80 Days 时间限制:1000ms 单点时限:1000ms 内存限制:256MB 描述 80 Days is an interesting game based on Jules Ve ...