zoukankan      html  css  js  c++  java
  • auto, extern, register, static

    对于一个数据的定义,需要指定2中属性:

    存储类型和数据类型:

    static int a;

    auto char c;

    register int d;

    1 auto

    2 extern

    3 register

    4 static

    5 作用域,可见域

    1 auto

    1 auto自动变量必须放在函数内部。

    3 register寄存器变量必须放在函数内部。

    1 auto自动变量,函数调用的时候,就存在,函数结束的时候,就终止。地址都是同一地址,但是内容却反复变化。

    4 static静态变量,一直存在,值没有变化,地址也没有变化。

    auto用于软件工程规范,让代码清晰易懂,如果只是为了程序可以跑起来,可加可不加。

    自动变量int num;等价于auto int num;

    自动变量int num=10;等价于auto int num=10;

    自动变量没有声明,只有定义。

    int num;

    int num=10;都是定义

    2 extern

    2 extern只有全局变量,没有局部变量。

    4 static既可以放在函数外部,也可以放在函数内部,外部是静态全局变量,内部是静态局部变量。

    同一个C文件,既可以访问static静态全局变量,也可以访问extern全局变量。

    static静态全局变量仅仅作用于当前的C文件。 

    extern全局变量的定义必须放在函数外部。

    需要用2个以上函数同时操作同一个变量,就必须使用全局变量。

    全局变量作用域是理论上的范围,也就是程序的任何部分,无论程序有几个C文件。

    作用域在任何地方,需要声明,没有合理的声明就无法使用。

    特定位置,是否可见,取决于是否合理声明。

    可见域,就是全局变量实际上可以引用的区域

    命名规则:全局变量用大写,局部变量用小写。

    创建全局变量比main函数还早。

    全局变量生命期就是程序的生命期,全局变量一直占内存,而局部变量用完就扔。

    需要谁都可以访问的场合就要全局变量。

    全局变量可以用于函数的通信,如信用卡账户,消费,还款。

    全局变量特定:生命周期很长,一直占用内存,除非程序退出;容易与局部变量重名,很容易就被屏蔽,失效。值容易被修改,例如游戏,遇到外挂一样的程序,遇到注入的黑客技术就容易被修改;全局变量可以被所有函数所共享。

    使用全局变量要注意:

    1名字要容易理解,尽可能不与局部变量重名。当函数内存与全局变量名相同的局部变量时,先用局部变量,没有局部变量用全局变量。

    2避免占内存较大的变量使用全局变量,节约内存。

    3避免全局变量被错误的修改。

    4正规的软件工程,写一个函数要修改全局变量,一定要注释:为什么修改,修改的目的是什么,修改的值是多少。

    extern全局变量有定义和声明的区别。

    声明只是声明变量的存在,定义就是全局变量的实体。

    全局变量声明:extern num;等价于extern int num;

    全局变量定义:extern num=10;等价于extern int num=10;

    声明可以多个,定义只有一个。

     1 #define _CRT_SECURE_NO_WARNINGS
     2 
     3 #include<stdio.h>
     4 #include<stdlib.h>
     5 
     6 int num;//声明
     7 int num;//声明
     8 int num = 10;//定义
     9 int num = 10;//重定义,报错
    10 
    11 main()
    12 {
    13     
    14 
    15     system("pause");
    16 }

    只有声明,不省略extern,没有定义,报错:

     1 #define _CRT_SECURE_NO_WARNINGS
     2 
     3 #include<stdio.h>
     4 #include<stdlib.h>
     5 
     6 extern int data;//仅仅有声明,没有定义,找不到data的实体
     7 extern int data;
     8 extern int data;
     9 
    10 main()
    11 {
    12     printf("%d
    ", data);
    13 
    14     system("pause");
    15 }

    严重性 代码 说明 项目 文件 行 禁止显示状态
    错误 LNK2001 无法解析的外部符号 _date hello F:usersdenggelindocumentsvisual studio 2015Projectshellohellohello.obj 1

    只有声明,省略extern,没有定义,正常,系统默认初始化为0:

     1 #define _CRT_SECURE_NO_WARNINGS
     2 
     3 #include<stdio.h>
     4 #include<stdlib.h>
     5 
     6 int data;//仅仅有声明,没有定义,找不到data的实体
     7 int data;
     8 int data;
     9 
    10 main()
    11 {
    12     printf("%d
    ", data);
    13 
    14     system("pause");
    15 }

    输出结果:

    0
    请按任意键继续. . .

    只有声明,省略extern,没有定义,数组,系统默认初始化为0:

     1 #define _CRT_SECURE_NO_WARNINGS
     2 
     3 #include<stdio.h>
     4 #include<stdlib.h>
     5 
     6 int a[3];
     7 int a[3];
     8 int a[3];//全部默认初始化为0
     9 
    10 main()
    11 {
    12     printf("%d
    ", a[0]);
    13     printf("%d
    ", a[1]);
    14     printf("%d
    ", a[2]);
    15 
    16     system("pause");
    17 }

    输出结果:

    0
    0
    0
    请按任意键继续. . .

    只有声明,省略extern,没有定义,结构体,系统默认初始化为0:

     1 #define _CRT_SECURE_NO_WARNINGS
     2 
     3 #include<stdio.h>
     4 #include<stdlib.h>
     5 
     6 struct info
     7 {
     8     int num;
     9     char str[50];
    10 };
    11 
    12 struct info info1;
    13 struct info info1;
    14 struct info info1;
    15 
    16 
    17 main()
    18 {
    19     printf("%d
    ", info1.num);
    20     printf("%s
    ", info1.str);
    21     printf("%d
    ", info1.num);
    22     printf("%s
    ", info1.str);
    23 
    24     system("pause");
    25 }

    输出结果:

    0

    0

    请按任意键继续. . .

    extern全局变量初始化:

     1 #define _CRT_SECURE_NO_WARNINGS
     2 
     3 #include<stdio.h>
     4 #include<stdlib.h>
     5 
     6 #define X 6
     7 
     8 enum info
     9 {
    10     A, B, C
    11 };
    12 
    13 int a = 10;//全局变量,10是一个常量
    14 //int b = a;//全局变量初始化不接受变量,只接受常量
    15 int c = 11 + 12;//常量表达式也可以
    16 int d = X;//#define常量是可以接受的
    17 int e = sizeof(a);//sizeof是可以接受的
    18 int f = A;//枚举常量是可以接受的
    19 
    20 const int g = 10;//不接受const,const不是真正意义上的常量,只是编译器为了保证代码不被乱修改而设定的机制
    21 //int h = g;//C语言的const是伪常量,仅仅适用于编译器禁止修改
    22 
    23 main()
    24 {
    25     system("pause");
    26 }

    3 register

    1 auto自动变量必须放在函数内部。

    3 register寄存器变量必须放在函数内部。

    register寄存器变量在CPU,没有内存地址。

    寄存器变量在CPU内部,速度快。

    所以频繁使用的变量,需要放在寄存器可以提高速度。

    VC会自动优化,即使没有声明寄存器变量,VC也会自动优化。

    GCC就不会自动优化。

    全局变量最好不要占用寄存器,占用了,会影响程序的速度。

    静态变量不可以放在寄存器。

    register static int num;会报错

    严重性 代码 说明 项目 文件 行 禁止显示状态
    错误 C2159 指定了一个以上的存储类 hello F:usersdenggelindocumentsvisual studio 2015Projectshellohellohello.c 17 

    4 static

    没有static相当于乱跳槽的人,每次都要重新开始。

    有static的人,等价于每次都在一个方向,要跳槽也是一个方向,就可以在一个方向达到很高的高度,每次都在积累。

    1 auto局部变量,每次块语句结束,就自动回收,然后重新分配。

    4 static静态局部变量,始终在内存,一旦定义初始化,即使再次执行初始化的语句,也仅仅执行一次初始化,生命周期一直占据内存,与程序共存亡。

    1 auto自动变量,函数调用的时候,就存在,函数结束的时候,就终止。地址都是同一地址,但是内容却反复变化。

    4 static静态变量,一直存在,值没有变化,地址也没有变化。

    2 extern只有全局变量,没有局部变量。

    4 static既可以放在函数外部,也可以放在函数内部,外部是静态全局变量,内部是静态局部变量。

    同一个C文件,既可以访问static静态全局变量,也可以访问extern全局变量。

    static静态全局变量仅仅作用于当前的C文件。 

    static静态局部变量,没有声明,只有定义。没有赋初值,编译器会自动赋值为0。

     

     1 #define _CRT_SECURE_NO_WARNINGS
     2 
     3 #include<stdio.h>
     4 #include<stdlib.h>
     5 
     6 main()
     7 {
     8     static int num;
     9     
    10     printf("%d
    ", num);
    11     
    12     system("pause");
    13 }

    static静态变量,也就是循环,函数调用这些场合经常新建变量,需要静态变量。

     1 #define _CRT_SECURE_NO_WARNINGS
     2 
     3 #include<stdio.h>
     4 #include<stdlib.h>
     5 #include<windows.h>
     6 
     7 #define X 10
     8 
     9 main()
    10 {
    11     for (;;)
    12     {
    13         static int x = 0;
    14         x++;
    15         printf("%d
    ", x);
    16         Sleep(1000);
    17     }
    18 
    19     system("pause");
    20 }

    输出结果:

    1

    2

    3

    static静态全局变量,区分声明和定义。

    static静态全局变量,如果没有赋值,恰好又引用,编译器会把声明当作定义,并自动赋值为0

    如果有多个声明,会把最后当作定义,其他当作声明

      

     1 #define _CRT_SECURE_NO_WARNINGS
     2 
     3 #include<stdio.h>
     4 #include<stdlib.h>
     5 
     6 static int num;
     7 static int num;
     8 static int num;//static静态全局变量,如果没有赋值,恰好又引用
     9 //编译器会把声明当作定义,并自动赋值为0
    10 //如果有多个声明,会把最后当作定义,其他当作声明
    11 
    12 static int num = 10;//定义,如果出现定义,就以定义为准
    13 
    14 main()
    15 {    
    16     printf("%d
    ", num);
    17     
    18     system("pause");
    19 }

    输出结果:

    10
    请按任意键继续. . .

    static静态全局变量,如果没有赋值,恰好又引用,编译器会把声明当作定义,并自动赋值为0

    同理适用于数组

     1 #define _CRT_SECURE_NO_WARNINGS
     2 
     3 #include<stdio.h>
     4 #include<stdlib.h>
     5 
     6 static int a[5];
     7 static int a[5];
     8 static int a[5];//static静态全局变量,如果没有赋值,恰好又引用,编译器会把声明当作定义,并自动赋值为0
     9 //同理适用于数组
    10 
    11 main()
    12 {    
    13     int i;
    14 
    15     for (i = 0;i < 5;i++)
    16     {
    17         printf("%d
    ", a[i]);
    18     }
    19     
    20     system("pause");
    21 }

    输出结果:

    0
    0
    0
    0
    0
    请按任意键继续. . .

    static静态全局变量,如果没有赋值,恰好又引用,编译器会把声明当作定义,并自动赋值为0

    同理适用于结构体

     1 #define _CRT_SECURE_NO_WARNINGS
     2 
     3 #include<stdio.h>
     4 #include<stdlib.h>
     5 
     6 struct info
     7 {
     8     int num;
     9     char name[20];
    10 };
    11 
    12 static struct info info1;
    13 static struct info info1;
    14 static struct info info1;
    15 
    16 
    17 main()
    18 {    
    19     printf("%d
    %s
    ", info1.num, info1.name);
    20     
    21     system("pause");
    22 }

    输出结果:

    0

    请按任意键继续. . .

    static静态全局变量和静态局部变量初始化:

     1 #define _CRT_SECURE_NO_WARNINGS
     2 
     3 #include<stdio.h>
     4 #include<stdlib.h>
     5 
     6 //static int num = a;//静态全局变量初始化不接受变量,只接受常量
     7 
     8 main()
     9 {
    10     //static int num = a;//静态局部变量初始化不接受变量,只接受常量
    11 
    12     system("pause");
    13 }

    static静态全局变量声明的作用:声明变量的存在,提升可见域。

    静态局部变量,让代码的移植性更强。

    把外部变量,移植到块语句内部,让代码移植性更强。

    C语言默认函数可以跨文件.c调用。

    static避免函数跨文件重名的问题。

    static避免本个源文件的函数被外部调用。

    用static说明函数:

    当定义一个函数时,若在函数返回值的类型前加上说明符static,则称此函数为静态函数,又叫内部函数。

    静态函数的特征是:只限于本编译单位的其他函数调用它,而不允许其他编译单位中的函数对它进行调用。

    使用静态函数可以避免不同编译单位因函数同名而引起混乱。

    static变量也可以作为函数参数

    软件工程规范,外部函数、内部函数的声明要求:

    1 //软件工程规范,内部函数这么声明
    2 void msg();
    3 void openqq();
    4 
    5 //软件工程规范,外部函数这么声明
    6 extern void msg();
    7 extern void openqq();

    静态局部变量

    静态局部变量把重名的静态全局变量覆盖了

     1 #include <iostream>
     2 
     3 static int a = 3;//静态全局变量
     4 
     5 void fun();
     6 
     7 void main()
     8 {
     9     for (int i = 1; i < a; i++)//a是静态全局变量
    10     {
    11         fun();
    12     }
    13 }
    14 
    15 void fun()
    16 {
    17     static int a = a;//a是静态局部变量,最初赋值为0
    18     std::cout << (a += 2) << std::endl;
    19 }

    输出结果:

    2
    4
    请按任意键继续. . .

    静态全局变量

     1 #include <iostream>
     2 
     3 static int a = 3;//静态全局变量
     4 
     5 void fun();
     6 
     7 void main()
     8 {
     9     for (int i = 1; i < a; i++)//a是静态全局变量
    10     {
    11         fun();
    12     }
    13 }
    14 
    15 void fun()
    16 {
    17     static int a = ::a;//左边a是静态局部变量,右边::a是静态全局变量
    18     std::cout << (a += 2) << std::endl;
    19 }

    输出结果:

    5
    7
    请按任意键继续. . .

    5 作用域,可见域

    作用域就是理论上函数可以调用的地方,可见域就是实际上可以调用的地方。

    结构体变量的作用域与可见域

     1 #define _CRT_SECURE_NO_WARNINGS
     2 
     3 #include<stdio.h>
     4 #include<stdlib.h>
     5 
     6 struct info//结构体类型定义在外部,就是从定义开始到当前源文件结束的范围
     7 {
     8     int num;
     9     char name[20];
    10 };
    11 
    12 struct info info1;
    13 
    14 main()
    15 {
    16     struct data//结构体类型定义在内部,就是从定义开始到当前块语句结束的范围
    17     {
    18         int num;
    19         char name[20];
    20     };
    21     
    22     system("pause");
    23 }

    结构体变量作为全局变量与局部变量:

     1 #define _CRT_SECURE_NO_WARNINGS
     2 
     3 #include<stdio.h>
     4 #include<stdlib.h>
     5 
     6 struct info//结构体类型定义在外部,就是从定义开始到当前源文件结束的范围
     7 {
     8     int num;
     9     char name[20];
    10 };
    11 
    12 //结构体变量作为全部变量,有声明与定义的差别。不赋值初始化就是声明,初始化就是定义。
    13 struct info info1;
    14 struct info info1;
    15 struct info info1;//都是声明,声明只是说明存在,可以有多个
    16 
    17 main()
    18 {
    19     //struct info info1;//结构体变量作为局部变量,没有声明与定义的区别,有没有初始化,都是定义
    20     
    21     struct info info1;
    22 
    23     //info1作为一个结构体变量,从当前定义开始,到当前的块语句结束,就是结构体变量的作用域
    24     
    25     info1.num = 10;
    26     
    27     system("pause");
    28 }

    不同的源文件引用外部结构体变量,不仅需要外部声明,还需要结构体定义

    结构体类型最多适用于1个c文件,不同的c文件快于包含同名同类型的结构体类型,也可以包含同名不同类型的结构体类型

    同一源文件中,函数外部,结构体类型定义最多只能有1个

    同一源文件中,同一个块语句中,结构体类型定义最多只能有1个,如果不同块语句,同名可以有多个

    栈区、堆区都是动态存储区,栈区调用的时候分配,用完的时候回收再次分配。

    堆区,自己自由分配,自己决定何时分配,何时回收。

    代码区、静态区,就一直存在,与程序共存亡。

  • 相关阅读:
    extjs 获取Dom对象
    转: python requests的安装与简单运用
    转: python如何安装pip和easy_installer工具
    转: windows下面安装Python和pip终极教程
    JS Json数据转换
    转:永久解决火狐浏览器出现的flash版本更新问题
    python 字符编码 转换
    opencv输出图片像素值
    Mac中安装tensorflow(转)
    在linux和Mac中访问某个文件夹中所有的文件
  • 原文地址:https://www.cnblogs.com/denggelin/p/5538620.html
Copyright © 2011-2022 走看看