C语言(五)extern和static关键字

一、extern与函数

如果一个程序由多个源文件,编译成功后会生成对应的多个目标文件,这些目标文件还不能单独运行,因为这些目标文件之间可能会有关联,比如:a.obj文件可能会调用c.obj中定义的一个函数。将这些相关的目标文件链接在一起后生成可执行文件

1.外部函数和内部函数

1)外部函数:如果在当前文件中定义的函数允许在其它文件访问、调用,就称为“外部函数”。C语言规定,不允许有同名的外部函数。

2)内部函数:如果在当前文件中定义的函数只能在内部使用,就称为“内部函数”。C语言对顶不同的源文件可以有同名的内部函数,并不互相干扰。

2.外部函数

因为所有的函数默认就是外部函数,所以extern关键字和auto一样,就是废的。

常见的做法:

①创建one.c文件,在里面定义一些函数。

②创建one.h文件,在里面对one.c定义的函数进行声明。

③在main.c文件中,包含one.h头文件即可使用里面的函数。

3.外部函数使用例子

one.c

#include <stdio.h>
void one(){
	printf("this is method one()\n");
}
void two(){
	printf("this is method two()\n");
}
void three(){
	printf("this is method three()\n");
}

one.h

#ifndef __C__one_h
	#define __C_one_h

		void one();
		void two();
		void three();
#endif

first.c

#include <stdio.h>
#include "one.h"
int main(){
	one();
	two();
	three();
	return 0;
}

执行指令:

gcc -c first.c one.c

gcc first.o one.o -o first.exe

first.exe

执行结果:

二、static与函数

1.定义内部函数

从上面的例子看出,one.c中定义的函数时可以被其他源文件访问的。其实有时候,我们想定义一个“内部函数”,不能被其他源文件访问的函数。只需使用static关键字修饰函数即可。

备注:

1)将上面的one函数用static关键字修饰一下,发现在链接的时候报错。

2)在编译阶段:编译器只检测单个源文件的语法是否不合理,并不测函数有没有定义;只有在链接的时候才会检测这个函数存不存在,也就是有没有被定义。

3)所谓编译:

就是单独检查每个源文件的语法是否合理,并不检查每个源文件之间的关联关系,一个源文件编译成功后就会生成一个目标文件。

所谓链接:就是检查目标文件的关联关系,将相关联的目标文件组合在一起,生成可执行文件。

2.声明和定义内部函数

#include <stdio.h>
static void test();
int main(int argc, const char * argv[])
{
    test();
    return 0;
}
static void test() {
    printf("调用了test函数");
}

三、static 、extern与函数的总结

1.static

在定义函数时,用static关键字进行修饰。内部函数又称为“静态函数”。这样该函数只能够在其定义的文件中使用,如果在不同的文件中有同名的外部函数,则互不干扰。

2.extern

使用extern关键字修饰的函数,就是外部函数,可以省略。默认定义的函数就是外部函数。

一个文件中想要调用其它文件中的外部函数,则需要再当前文件中使用extern声明该函数,然后就可使用,extern也可以省略。

四、static/extern与变量

1.全局变量的位置

在java中全局变量的位置是没有要求的。但是在C语言中,全局变量定义的位置是有限制的。默认一个函数不能访问在它后面定义的全局变量。

解决方法:

方法一:将全局变量定义到前面。

方法二:在前面用extern进行声明。

2.重复定义同一个变量

在C语言中,可以重复定义某个变量,它们始终代表的是同一个变量。

#include <stdio.h>
int a=10;
int main(){
	extern int a;    //表示引用全局变量,其实是多次一举,这行是多余的
	a=12;            //为全部变量重新赋值
	printf("%d\n",a);
	return 0;
}
int a;
 //执行成功
#include <stdio.h>
int a=10;	//全局变量
int main(){
	int a =12;//局部变量,和全部变量a之间没有任何关系
	printf("%d\n",a);
	return 0;
}
int a;

3.不同源文件中的同名变量

在2个源文件中定义同一个变量,它们代表的都是同一个变量。

one.c

#include <stdio.h>
int a;
 void one(){
	printf("%d\n",a);
}

first.c

#include <stdio.h>
int a ;
void one();
int main(){
	a =12;
	one();
	return 0;
}

4.extern关键字

必须有已经声明过变量,才能使用extern关键字引用该变量。

例如:one.c中定义int a;在main.c中引用该变量,extern int a

但是不允许两边都使用extern修饰,因为都没定义,如何引用。

5.static

私有的全部变量:使用static关键字修饰的变量。该变量只能在该源文件内有效。

6.总结

1)extern可以用来引入一个全局变量。

2)默认情况下,一个变量是可以供多个源文件共享的,也就是说,多个源文件中同名的全局变量都代表着同一个变量。

3)如果在定义全局变量的时候加上static关键字,那么该全局变量仅限于定义该变量的源文件。与其它源文件中的同名变量互不干扰。

时间: 2024-10-12 16:06:52

C语言(五)extern和static关键字的相关文章

C语言学习笔记(二) static关键字详细分析

C语言代码是以文件为单位来组织的,在一个源程序的所有源文件中,一个外部变量(注意不是局部变量)或者函数只能在一个源程序中定义一次,如果有重复定义的话编译器就会报错.伴随着不同源文件变量和函数之间的相互引用以及相互独立的关系,产生了extern和static关键字. 关键字static有着不寻常的历史.起初,在C中引入关键字static是为了表示退出一个块后仍然存在的局部变量.随后,static在C中有了第二种含义:用来表示不能被其它文件访问的全局变量和函数.为了避免引入新的关键字,所以仍使用st

黑马程序员——c语言的extern与static

知识点: 外部函数:定义的函数能被本文件和其他文件访问 1> 默认情况下所有函数都是外部函数 2> 不允许有同名的外部函数 内部函数:定义的函数只能被本文件访问,其他文件不能访问 1> 允许不同文件中有同名的内部函数 static对函数的作用: 1> 定义一个内部函数 2> 声明一个内部函数 extern对函数的作用: 1> 完整地定义一个外部函数 2> 完整地声明一个外部函数 (extern可以省略,默认情况下声明和定义的函数都是外部函数) 一.extern与函

[C]控制外部变量访问权限的extern和static关键字

一.extern 概述 编译器是由上至下编译源文件的,当遇到一些函数引用外部全局变量,而这个变量被定义在该函数声明主体的下方,又或者引用自其它的编译单元,这个情况就需要extern来向编译器表明此变量是一个外部变量 问题1.运用extern实现全局变量声明提升效果 #include <stdio.h> void fun(void); int main(void) { fun(); } void fun(void) { printf("%d\n", v); } int v =

关于extern和static关键字引出的一些关于作用域和链接属性和存储类型的问题

在进入正题前我们必须了解一些概念: 标识符:标识符不仅仅代表着变量的名字,main()函数的main也是一个标识符,这点很重要. 存储类型:即变量的存储位置及其生存周期:静态区:分为两块 .date 已显式初始化的全局变量了静态变量 .bss 存放未初始化的全局或者静态变量 注意:静态变量的初值是在编译时就进行初始化了:意思就是用static修饰的变量赋过数值的话就保存为他的初值,如果没有初始化的话就赋值为零,且整个程序只初始化一次:即不管static int i = 1:或者这 static

extern和static关键字

1.对函数的应用 static 声明和定义内部函数时都要加 extern 一般的函数就是外部函数,不需要extern 2.对变量的应用 extern:访问其他文件中的全局变量 头文件不能定义变量,否则链接期报错(不清楚为啥,不过,一般也不这么做.详见:永远不要在.h文件中定义变量!) 例子: fun.c int a = 100; main.c extern int a; //声明外部全局变量 extern只能用来声明变量,表明变量是外来变量,不能用来定义变量 如果引用的变量是外来变量,不写ext

static关键字 详解

原文地址:http://blog.csdn.net/keyeagle/article/details/6708077 google了近三页的关于C语言中static的内容,发现可用的信息很少,要么长篇大论不知所云要么在关键之处几个字略过,对于想挖掘底层原理的初学者来说参考性不是很大.所以,我这篇博文博采众家之长,把互联网上的资料整合归类,并亲手编写程序验证之. C语言代码是以文件为单位来组织的,在一个源程序的所有源文件中,一个外部变量(注意不是局部变量)或者函数只能在一个源程序中定义一次,如果有

链接(extern、static关键词\头文件\静态库\共享库)

原文链接:http://www.orlion.ga/781/ 一. 多目标文件的链接 假设有两个文件:stack.c: /* stack.c */ char stack[512]; int top = -1; void push(char c) {         stack[++top] = c; } char pop(void) {         return stack[top--]; } int is_empty(void) {         return top == -1; }

static关键字分析【转】

本文转载自:http://flyingcat2013.blog.51cto.com/7061638/1564695 C语言代码是以文件为单位来组织的,在一个源程序的所有源文件中,一个外部变量(注意不是局部变量)或者函数只能在一个源程序中定义一次,如果有重复定义的话编译器就会报错.伴随着不同源文件变量和函数之间的相互引用以及相互独立的关系,产生了extern和static关键字. 关键字static有着不寻常的历史.起初,在C中引入关键字static是为了表示退出一个块后仍然存在的局部变量.随后,

C语言关键字register、extern、static、一些总结,及项目中使用的心得

首先介绍两个概念: 一.变量的生存周期: 变量从建立到撤销的时间段成变量的生存周期.静态变量,从变量产生到整个程序执行结束.当函数使用变量结束后,变量的存储空间依然存在,变量的值也会随着函数的对其的使用而改变.如在函数内定义了一个static变量,那第一次调用该函数后,该变量的值将会被保留,当第二次被调用时,该变量的值还是第一次调用结束时的值.动态变量,顾名思义,变量的存储空间是随着函数的调用动态产生和撤销的.如,在一个函数里定义了动态变量,变量的周期指从变量建立到函数结束,而不是这个程序结束.