C语言基础——extern 与 static


一、extern与函数


外部函数:如果在当前文件中定义的函数允许其他文件访问、调用,就称为外部函数。C语言规定,不允许有同名的外部函数。
内部函数:如果在当前文件中定义的函数不允许其他文件访问、调用,只能在内部使用,就称为内部函数。C语言规定不同的源文件可以有同名的内部函数,并且互不干扰。


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


例如,main.c
// 声明一个test函数
// 完整地声明一个外部函数
// extern可以省略
//extern void test();
void test();

//void test2();

int main()
{
    test();
    
    //test2();
    return 0;
}

//void test()
//{
//    
//}
static void test2()
{
    
}



one.c

#include <stdio.h>

// 声明一个内部函数
static void test2();

// 完整地定义一个外部函数
/*
extern void test()
{
    printf("调用了test函数\n");
}*/
// 默认情况下,所有的函数都是外部函数,所以可以省略extern
void test()
{
    printf("调用了test函数\n");
    
    test2();
}


// 定义一个内部函数
static void test2()
{
    printf("调用了test2函数\n");
}


二、static与函数

1.定义内部函数
从上面的例子可以看出,one.c中定义的one函数是可以被其他源文件访问的。其实有时候,我们可能想定义一个"内部函数",也就是不想让其他文件访问本文件中定义的函数。这个非常简单,你只需要在定义函数的时候加个static关键字即可。


  #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可以把该函数声明为内部函数(又叫静态函数),这样该函数就只能在其定义所在的文件中使用。如果在不同的文件中有同名的内部函数,则互不干扰。


* static也可以用来声明一个内部函数


 


2.extern
* 在定义函数时,如果在函数的最左边加上关键字extern,则表示此函数是外部函数,可供其他文件调用。C语言规定,如果在定义函数时省略extern,则隐含为外部函数。


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



四、static、extern与变量


全局变量分2种:
 外部变量:定义的变量能被本文件和其他文件访问
 1> 默认情况下,所有的全局变量都是外部变量
 1> 不同文件中的同名外部变量,都代表着同一个变量
 
 内部变量:定义的变量只能被本文件访问,不能被其他文件访问
 1> 不同文件中的同名内部变量,互不影响
 
 static对变量的作用:
 定义一个内部变量
 
 extern对变量的作用:
 声明一个外部变量
 
 static对函数的作用:
 定义和声明一个内部函数
 
 extern对函数的作用:
 定义和声明一个外部函数(可以省略)

例如,

#include <stdio.h>

void test();

// 定义一个外部变量

//int a; 这么多个a都是代表同一个a
//int a;
//int a;
//int a;
//int a;


// 定义一个内部变量
static int b;

// 声明一个外部变量
//extern int a;

int main()
{
    //b = 10;
    
    //test();
    
    extern int a;
    a = 10;
    
    /*
    a = 10;
    
    test();
    
    printf("a的值是%d\n", a);*/
    
    return 0;
}


int a;

#include <stdio.h>

int a;

static int b;

void test()
{
    printf("b的值是%d\n", b);
    
    /*
    printf("a的值是%d\n", a);
    
    a = 20;*/
}


static修饰局部变量

1. 延长局部变量的生命周期:程序结束的时候,局部变量才会被销毁
2 .并没有改变局部变量的作用域
3 .所有的test函数都共享着一个变量b


static修饰局部变量的使用场合:
1.如果某个函数的调用频率特别高
2.这个函数内部的某个变量值是固定不变的


#include <stdio.h>
void test()
{
    static double pi = 3.14;
    
    double zc = 2 * pi * 10;
    
    int a = 0;
    a++;
    printf("a的值是%d\n", a); // 1
   
    static int b = 0;
    b++;
    printf("b的值是%d\n", b); // 3
}

int main()
{
    for (int i = 0; i<100; i++) {
        test();
    }
    
    
    test();
    
    test();
    
    test();
    
    
    return 0;
}


五、static和extern的总结



1.extern可以用来声明一个全局变量,但是不能用来定义变量


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


3.如果在定义全局变量的时候加上static关键字,此时static的作用在于限制该全局变量的作用域,只能在定义该全局变量的文件中才能使用,跟其他源文件中的同名变量互不干扰


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值