深度理解C语言中的关键字static

目录
  • 一、函数和变量的多文件问题
    • 1.1.为什么全局变量和函数需要跨文件访问
  • 二、static修饰变量和函数
    • 2.1.static修饰全局变量
    • 2.2.static修饰局部变量
    • 2.3.为什么局部变量具有临时性,全局变量具有全局性
  • 总结

一、函数和变量的多文件问题

.h: 头文件,一般包含函数声明,变量声明,宏定义,头文件等内容(header)
.c : 源文件,一般包含函数实现,变量定义等 (.c:c语言)

如果在一个源文件定义一个函数,然后再另一个源文件调用,这样的方式可行吗?

答案是可行的,但是在生成解决方案的时候会警告:

但是如果把函数换成变量的话,则无法运行:

如果要使用这个变量,就必须加入声明:

注意在声明的时候不能赋值:

这个很好理解,因为声明并没有开辟内存空间。

为什么要有头文件?

从上面不难看出,当单纯使用源文件组织项目的时候是十分麻烦的,比如一个文件要使用另一个文件的变量就必须要声明,当项目非常复杂的时候维护成本会非常高。

所以为了解决这个问题,我们把函数声明,以及很多文件都需要用到的变量声明、宏定义、头文件包含等放到头文件中,源文件想要用的时候只需要包含头文件即可。这样即可减少项目的维护成本。

变量声明必须要加extern,函数声明可以不加

到此为止,我们就知道了:

全局变量,是可以跨文件被访问的。全局函数,是可以跨文件被访问的。

1.1.为什么全局变量和函数需要跨文件访问

对于有一定规模的项目,一定是多文件的,多个文件之间一定会有数据的“交互”(比如在main.c中访问test.c的函数),所以如果不能跨文件访问,文件之间“交互”成本就非常高。

对于一些需要隐藏起来不想被其他文件访问的变量或者函数,就可以用static修饰。

二、static修饰变量和函数

2.1.static修饰全局变量

static修饰全局变量,代表该变量只能在本文件内被访问,不能在其他文件直接访问。

虽然其他文件不能直接访问,但是可以通过本文件的函数访问:

static修饰全局函数也是一样。

对于全局变量和全局函数,static修饰的是变量和函数的作用域。

2.2.static修饰局部变量

static修饰局部变量,修饰的是变量的生命周期,变量的生命周期变成全局周期。(作用域不变)。

且该变量的初始化只会在定义的时候进行一次,后续将不再进行初始化,因为定义只能定义一次。

在这里fun函数结束后,变量i并没有被释放,它的生命周期是全局周期。

注意这里i的作用域没变,在函数外是不能访问i的。

2.3.为什么局部变量具有临时性,全局变量具有全局性

static修饰的局部变量和全局变量会被放在静态区,静态区在整个“进程”运行生命周期内都是有效的。而局部变量则会被放到栈区,栈区的变量具有临时性,因为栈区有入栈(开辟空间)和出栈(释放空间)的过程。

总结

到此这篇关于C语言中关键字static的文章就介绍到这了,更多相关C语言关键字static内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • C语言static修饰函数详细解析

    在C语言中,static的字面意思很容易把我们导入歧途,其实它的作用有三条.介绍它的第一条也是最重要的一条:隐藏.当我们同时编译多个文件时,所有未加static前缀的全局变量和函数都具有全局可见性.为理解这句话,我举例来说明.我们要同时编译两个源文件,一个是a.c,另一个是main.c. 下面是a.c的内容 复制代码 代码如下: char a = 'A'; // global variablevoid msg() {    printf("Hello\n"); } 下面是main.c的

  • c语言中static和extern的用法详细解析

    一,static和extern:大工程下我们会碰到很多源文档. 文档a.c 复制代码 代码如下: static int i; //只在a文档中用int j;    //在工程里用static void init()         //只在a文档中用{}void callme()          //在工程中用{   static int sum;} 上面的全局i变量和init()函数只能用在a.c文档中,全局变量sum的作用域只在callme里.变量j和函数callme()的全局限扩充到整个

  • C语言中static的作用及C语言中使用静态函数有何好处

    想了解Java中static关键字的作用和用法详细介绍,请点击此处了解详情. 在C语言中,static的字面意思很容易把我们导入歧途,其实它的作用有三条,分别是: 一是隐藏功能,对于static修饰的函数和全局变量而言 二是保持持久性功能,对于static修饰的局部变量而言. 三是因为存放在静态区,全局和局部的static修饰的变量,都默认初始化为0 下面我逐一给大家介绍: (1)先来介绍它的第一条也是最重要的一条:隐藏. 当我们同时编译多个文件时,所有未加static前缀的全局变量和函数都具有

  • 快速了解C语言静态关键字static的作用

    静态关键字static C语言中,static关键字修饰变量和函数 1.局部变量 2.全局变量 3.函数 修饰局部变量 1.用静态关键字static修饰的局部变量,在编译的过程中,会在数据区为该变量开辟空间,并对其进行初始化,如果代码中未对其进行初始化,则系统默认初始化为0 2.用static修饰的局部变量,会延长局部变量的寿命,超出函数的生存期 3.对静态关键字修饰的局部变量的初始化 以下面两个变量a和变量为b进行说明,在编译过程中,发现变量a和b是静态变量,会标识变量a与b,等到程序运行的时

  • 深入理解C语言 static、extern与指针函数

    1.exit(0)正常退出程序 exit(1)程序异常时退出程序 2.static(静态变量)修饰局部变量 在局部变量使用static修饰,会延长局部变量的存在期.但我们需要注意一下几点: •虽然static修饰变量的生存期很长,但它始终是局部变量,不能在其他函数中使用•static全局变量与普通的全局变量有什么区别?static局部变量和普通局部变量有什么区别?static函数与普通函数有什么区别?     全局变量(外部变量)的说明之前再冠以static 就构成了静态的全局变量.全局变量本身

  • c语言中static的用法详细示例分析

    static在c里面可以用来修饰变量,也可以用来修饰函数.先看用来修饰变量的时候.变量在c里面可分为存在全局数据区.栈和堆里.其实我们平时所说的堆栈是栈而不是堆,不要弄混. 复制代码 代码如下: int a ;int main(){    int b ;     int c* = (int *)malloc(sizeof(int));} a是全局变量,b是栈变量,c是堆变量.static对全局变量的修饰,可以认为是限制了只能是本文件引用此变量.有的程序是由好多.c文件构成.彼此可以互相引用变量,

  • 深度理解C语言中的关键字static

    目录 一.函数和变量的多文件问题 1.1.为什么全局变量和函数需要跨文件访问 二.static修饰变量和函数 2.1.static修饰全局变量 2.2.static修饰局部变量 2.3.为什么局部变量具有临时性,全局变量具有全局性 总结 一.函数和变量的多文件问题 .h: 头文件,一般包含函数声明,变量声明,宏定义,头文件等内容(header) .c : 源文件,一般包含函数实现,变量定义等 (.c:c语言) 如果在一个源文件定义一个函数,然后再另一个源文件调用,这样的方式可行吗? 答案是可行的

  • 深度解析C语言中的变量作用域、链接和存储期的含义

    在c中变量有三种性质: 1.存储期限:变量的存储期限决定了变量占用的内存空间什么时候会被释放,具有动态存储期限的变量会在所属的程序块被执行时获得内存空间,在结束时释放内存空间.具有静态存储期限的变量在程序运行的整个期间都会占用内存空间. 2.作用域:变量有块作用域也有文件作用域,结合序章第一张图可以明白块作用域是在某些程序块内起作用,文件作用域是在整个c文件之内起作用. 3.链接:链接是各个文件之间的关系,具有内部链接的变量只在本文件内起作用,具有外部链接的变量可以在不同文件内起作用.具有无链接

  • C语言入门篇--关键字static详解

    目录 1.修饰局部变量 1.1作用 1.2举例 (1)不加static (2)加static (3)静态局部变量的初始化只会进行一次 2.修饰全局变量 2.1作用 2.2举例 (1)不加static (2)加static 3.修饰函数 3.1作用 3.2举例 (1)不加static (2)加static 1.修饰局部变量 1.1作用 ststic修饰局部变量,会改变局部变量的生命周期,不改变作用域: 生命周期:和全局变量一样具有全局性,但在内存中的位置没有改变,还在在静态存储区中. 作用域:作用

  • 深度解析C语言中数据的存储

    目录 前言 数据类型介绍 类型的基本归类 整型家族 浮点数家族 构造类型 指针类型 空类型 前言 在VS编译器里有release和debug两种形式,debug包含调试信息,release不包含调试信息,并会对程序进行优化 int main() { int i = 0; int arr[10] = { 1,2,3,4,5,6,7,8,9,10 }; for (i = 0; i <= 12; i++) { arr[i] = 0; printf("hehe\n"); } return

  • Delphi之Pascal语言中的关键字及保留字汇总

    本文汇总了Pascal语言中的关键字及保留字如下,供大家参考: absolute//指令(变量) abstract//指令(方法) and//运算符(布尔) array//类型 as//运算符(RTTI) asm//语句 assembler//向后兼容(汇编) at//语句(异常处理) automated//访问类别符(类) begin//块标记 case//语句 cdecl//函数调用协定 class//类型 const//声明或指令(参数) constructor//特殊方法 contain

  • 深入理解 Go 语言中的 Context

    Hi,大家好,我是明哥. 在自己学习 Golang 的这段时间里,我写了详细的学习笔记放在我的个人微信公众号 <Go编程时光>,对于 Go 语言,我也算是个初学者,因此写的东西应该会比较适合刚接触的同学,如果你也是刚学习 Go 语言,不防关注一下,一起学习,一起成长. 我的在线博客:http://golang.iswbm.com 我的 Github:github.com/iswbm/GolangCodingTime 1. 什么是 Context? 在 Go 1.7 版本之前,context 还

  • 深度解密 Go 语言中的 sync.map

    工作中,经常会碰到并发读写 map 而造成 panic 的情况,为什么在并发读写的时候,会 panic 呢?因为在并发读写的情况下,map 里的数据会被写乱,之后就是 Garbage in, garbage out,还不如直接 panic 了. 是什么 Go 语言原生 map 并不是线程安全的,对它进行并发读写操作的时候,需要加锁.而 sync.map 则是一种并发安全的 map,在 Go 1.9 引入. sync.map 是线程安全的,读取,插入,删除也都保持着常数级的时间复杂度. sync.

  • 带你理解C语言中的汉诺塔公式

    目录 汉诺塔公式 汉诺塔问题在数学层面的公式: C语言递归公式 两层汉诺塔 三层汉诺塔 总结 汉诺塔公式 汉诺塔问题在数学层面的公式: 不用说,你看到这个公式一定一脸懵逼,我现在来讲解这个公式的作用. 先来回想一下大象放冰箱要几步,三步吧,打开冰箱,放进去,关上门就行了,我们先不要去思考一些细碎的步骤,将一个复杂的问题先简单化,再慢慢去分析. 那汉诺塔问题也是同样的简单三步:(假设有n个盘子) 一.把最大的盘子留在A柱,然后将其他的盘子全放在B柱. 二.把最大的盘子放到C柱. 三.然后将B柱上的

  • 深度解密Go语言中字符串的使用

    目录 Go 字符串实现原理 字符串的截取 字符串和切片的转换 字符串和切片共享底层数组 什么是万能指针 字符串和其它数据结构的转化 整数和字符串相互转换 Parse 系列函数 Format 系列函数 小结 Go 字符串实现原理 Go 的字符串有个特性,不管长度是多少,大小都是固定的 16 字节. package main import (     "fmt"     "unsafe" ) func main() {     fmt.Println(         

  • 深度解密 Go 语言中的 sync.Pool

    最近在工作中碰到了 GC 的问题:项目中大量重复地创建许多对象,造成 GC 的工作量巨大,CPU 频繁掉底.准备使用 sync.Pool 来缓存对象,减轻 GC 的消耗.为了用起来更顺畅,我特地研究了一番,形成此文.本文从使用到源码解析,循序渐进,一一道来. 是什么 sync.Pool 是 sync 包下的一个组件,可以作为保存临时取还对象的一个"池子".个人觉得它的名字有一定的误导性,因为 Pool 里装的对象可以被无通知地被回收,可能 sync.Cache 是一个更合适的名字. 有

随机推荐