关于static全局变量与普通全局变量的区别

qq283802332 2013-10-28 10:47:04
这是在书上看到的一个static全局变量与普通全局变量的一个区别说明

1) 全局变量(外部变量)的说明之前再冠以static 就构成了静态的全局变量。全局变量本身就是静态存储方式, 静态全局变量当然也是静态存储方式。 这两者在存储方式上并无不同。这两者的区别在于非静态全局变量的作用域是整个源程序, 当一个源程序由多个源文件组成时,非静态的全局变量在各个源文件中都是有效的。静态全局变量则限制了其作用域, 即只在定义该变量的源文件内有效, 在同一源程序的其它源文件中不能使用它。由于静态全局变量的作用域局限于一个源文件内,只能为该源文件内的函数公用,因此可以避免在其它源文件中引起错误。

这是源文件1.h

int a = 2; //普通全局变量
static int s = 5; //static全局变量


这是源文件2.h

int b = 3; //普通全局变量


这是main.c

#include <stdio.h>
#include "1.h"
#include "2.h"

int func()
{
return s;
}

int main()
{
printf("%d\n", a);
printf("%d\n", b);

printf("%d\n", s); //这里有问题
}


在printf("%d\n", s)中, s这个变量是我在1.h这个头文件中定义的一个static全局变量, 而从上面的说明中可以知道static去阿奴姐变量限制了其作用域, 即之灾定义该变量的源文件内有限(即在1.h中有限)。
在同一源程序的其它源文件中不能使用它。可是我却可以在main.c中使用这个变量, 这是不是矛盾了
这个是我现在理解不了的地方, 请各位code monkey讲解一下
...全文
28180 11 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
还有多远 2013-10-30
  • 打赏
  • 举报
回复
引用 3 楼 baipv008 的回复:
[quote=引用 楼主 qq283802332 的回复:] 定义该变量的源文件内有限(即在1.h中有限)。
你的核心错误在于: .h不是源文件,源文件是指.c或.cpp[/quote] 嗯,#include <*.h>语句的效果就是预处理时将*.h的全部内容复制到使用include语句的文件中
fengidri 2013-10-30
  • 打赏
  • 举报
回复
编译的过程有好几步的,在给gcc编译之前是预处理,预处理时把include包括的文件加进来,之后这个文件给gcc进行编译。这时候才是真正意义上的源文件。 定义与申明是不同的,申明可以放到头文件中去,但是定义是不能放到头文件中的。 定义与申明的不同在于申明是给编译器看的,但是定义会分配内存。你使用 static int s;这个时候就已经分配了一个内存。这是定义,怎么能放到内存里呢?
ooolinux 2013-10-29
  • 打赏
  • 举报
回复
比如一个项目里面有2个.c源文件(互相不能#include,include .c文件不规范),一个文件定义了static全局变量a,另一个文件就无法用extern a声明这个外部变量,非static就可以。
zhao 2013-10-29
  • 打赏
  • 举报
回复
函数体内static变量的作用范围为该函数体,改变量只被分配一次,其值在下次调用的时候扔维持上次调用的值。 模块内的static全局变量可以被模块内的所有函数访问,但不能被模块外的其他函数访问。 模块内的static函数只能被该模块内部的其他函数调用,这个函数的使用范围被限制在该模块内部。 C++中另有类: 类中static成员属于整个类所有,对类的所有对象只有一份拷贝 类中static成员函数属于整个类所有,这个函数不接受this指针,因而只能访问类的static成员变量。 你没搞清楚.h .c区别。.h仍是模块的一部分。include了.h就把.h的所有内容放在了.c中,直接使用命令行gcc -E file..c -o file.i看看结果
绿皮蛙 2013-10-28
  • 打赏
  • 举报
回复
楼主只要知道 编译器是怎么处理#include的 就是直接把那些文件内容拷贝进来 然后再编译的 就是和你直接写在那个点c里是一样的
zmn0079 2013-10-28
  • 打赏
  • 举报
回复
楼上几位都说得对 楼主你明明已经include了1.h,当然被视为同一个文件了
图灵狗 2013-10-28
  • 打赏
  • 举报
回复
你的理解没有错,但是例子给错了,#include的话,展开之后相当于static在main中仍然是可见的。你把static放在.h文件中是无意义的,且很容易被重复引用而形成重复定义。正确的做法是在.c中定义全局变量,而在.h中用extern引出全局变量,当然static变量是无法extern的。
引用 楼主 qq283802332 的回复:
这是在书上看到的一个static全局变量与普通全局变量的一个区别说明 1) 全局变量(外部变量)的说明之前再冠以static 就构成了静态的全局变量。全局变量本身就是静态存储方式, 静态全局变量当然也是静态存储方式。 这两者在存储方式上并无不同。这两者的区别在于非静态全局变量的作用域是整个源程序, 当一个源程序由多个源文件组成时,非静态的全局变量在各个源文件中都是有效的。静态全局变量则限制了其作用域, 即只在定义该变量的源文件内有效, 在同一源程序的其它源文件中不能使用它。由于静态全局变量的作用域局限于一个源文件内,只能为该源文件内的函数公用,因此可以避免在其它源文件中引起错误。 这是源文件1.h

int a = 2;                //普通全局变量
static int s = 5;         //static全局变量
这是源文件2.h

int b = 3;                //普通全局变量
这是main.c

#include <stdio.h>
#include "1.h"
#include "2.h"

int func()
{
    return s;
}

int main()
{
    printf("%d\n", a);
    printf("%d\n", b);

    printf("%d\n", s);        //这里有问题
}
在printf("%d\n", s)中, s这个变量是我在1.h这个头文件中定义的一个static全局变量, 而从上面的说明中可以知道static去阿奴姐变量限制了其作用域, 即之灾定义该变量的源文件内有限(即在1.h中有限)。 在同一源程序的其它源文件中不能使用它。可是我却可以在main.c中使用这个变量, 这是不是矛盾了 这个是我现在理解不了的地方, 请各位code monkey讲解一下
千树之影 2013-10-28
  • 打赏
  • 举报
回复
引用 楼主 qq283802332 的回复:
定义该变量的源文件内有限(即在1.h中有限)。
你的核心错误在于: .h不是源文件,源文件是指.c或.cpp
lm_whales 2013-10-28
  • 打赏
  • 举报
回复
C:static 函数外部定义,是文件静态变量,作用域为文件,生命周期是程序生命期。 函数内定义,是函数内部的静态变量,作用域为函数,生命周期是程序生命期。 其中,函数中,语句组的内部静态变量,作用域为该语句组,生命周期是程序生命期。 C++: 文件内的,匿名命名空间内,定义的变量,相当于文件静态变量。 作用域为文件,生命周期是程序生命期。 类内部定义的静态变量,作用域为类,生命周期是程序生命期。 可以使用的区域是类, 友元类或友元函数,以及定义类的区域,这些和友元,访问权等有关。 类的作用域对友元是开放的。子类也有可能可以使用。 对定义类的区域是否开放和访问权限等有关。 其中 public 定义的静态变量, 在定义类的区域,可以通过类名访问。 和函数不同,函数内部定义的静态变量; 不可用在其他地方,只能通过函数调用访问。 类内部定义的静态变量,可以直接在类外部,通过类名引用。
九月草长 2013-10-28
  • 打赏
  • 举报
回复
头文件声明普通全局变量不妥,如果多个源文件引用会有重定义错误 一般头文件里面用extern 声明为外部全局变量吧,然后在某个源文件里面真正定义。
AnYidan 2013-10-28
  • 打赏
  • 举报
回复
一般而言,定义变量在 c 文件中,声明变量在 h 文件中

70,023

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧