C高阶3:变量分类

2019-04-14  本文已影响0人  jdzhangxin

1. 本地变量/局部变量

1.1 本地变量/局部变量是什么?

在大括号内定义的变量就是本地变量/局部变量。

1.2 本地变量/局部变量有什么特点?

  1. 本地变量是定义在代码块内的,可以定义在函数的块内,可以定义在语句的块内。
for(int i=0;i<10;++i){
    printf("%d ",i);
}
printf("%d ",i);

可以定义在一个随意的大括弧里面。

{
    int n = 0;
    printf("%d ",n);
}
printf("%d ",n);
  1. 程序进入块前,内部变量不存在,离开时失效
  2. 块外定义的变量,块内仍然有效。

函数的每次运行,都会产生一个独立的变量空间,在这个空间中的变量,是函数这次运行独有的。

  • 定义在函数内部的变量就是本地变量
  • 参数也是本地变量

1.3 本地变量/局部变量初始化

  1. 本地变量不会默认初始化
  2. 参数在进入函数时被初始化。

本地变量/局部变量的生存期和作用域都是在大括号内。

2. 全局变量

2.1 全局变量是什么?

定义在函数外面的变量称为全局变量

int n;
int main(){
    int m;
    printf("n=%d\m=%d\n",n,m);
}

2.2 全局变量有什么特点?

全局变量有全局的生存周期和作用域。

  1. 不属于任何函数。
  2. 所有函数内部都可以使用。
int n;
int func(){
    printf("in func n = %d\n",n);
    // n = n*2;
}
int main(){
    scanf("%d",&n);
    func();
    printf("in main n = %d\n",n);
}

2.3 全局变量初始化

  1. 没有初始化的全局变量会自动初始化为0
  2. 只能用编译时刻已知的值初始化全局变量。
  3. 初始化发生在main()前。
int n = 2;
int m = n;
double  s = sqrt(n); 
int main(){
    printf("n = %d,m = %d,s = %f",n,m,s);
}

2.4 同名隐藏

如果函数内部存在与全局变量同名的变量,则全局变量被隐藏。

int n = 10;
int main(){
    int n = 1;
    printf("n = %d\n",n);
}

3. 全局静态变量

3.1 全局静态变量是什么?

在全局变量前加上关键字static

static int n;
int main(){
    int m;
    printf("n=%d\m=%d\n",n,m);
}

3.2 全局变量与全局静态变量区别

  1. 若程序由一个源文件构成时,全局变量与全局静态变量没有区别。
  2. 若程序由多个源文件构成时,全局变量与全局静态变量不同:全局静态变量使得该变量成为定义该变量的源文件所独享,即:全局静态变量对组成该程序的其它源文件是无效的。
  3. 具有外部链接的静态,可以在所有源文件里调用,除了本文件,其他文件可以通过extern的方式引用。

4. 本地静态变量

4.1 静态本地变量是什么?

在本地变量定义时加上static变成静态本地变量。

4.2 静态本地变量有什么特点?

当函数离开时,静态本地变量会继续存在并保存其值。

int inc(){
    static int n = 1;
    n = n + 1;
    return n;
}
int main(){
    printf("%d\n",inc());
    printf("%d\n",inc());
    printf("%d\n",inc());
}

静态本地变量的初始化在第一次进入函数时执行,以后进入函数会保持离开的值。
静态本地变量是特殊的全局变量,具有全局生存周期和局部作用域。

5. 总结

5.1 变量的作用域和生命期

No. 分类 作用域 生命期
1 局部变量 所在代码块内 所在函数结束
2 全局变量 所有文件内 程序执行结束
3 静态局部变量 所在代码块内 程序执行结束
4 静态全局变量 当前文件内 程序执行结束
5 普通函数 所有文件内 -
6 静态函数 当前文件内 -

6. static关键字小结:

static在C语言里面既可以修饰变量,也可以修饰函数。

不对外公开的函数和全局变量
在函数前面加上static就使它成为只能所在编译文件中使用的函数。
在全局变量前加上static使它成为只能所在编译文件中使用的全局变量。

7. 最佳实践

7.1 不要返回本地变量的指针

  1. 返回本地变量的地址是危险的。
  2. 返回全局变量或静态本地变量的地址是安全的。
  3. 返回函数内的动态内存是安全的,但注意要记得释放。
  4. 最好的做法是返回传入的指针。

7.2 慎用静态变量

不要使用全局变量在函数间传递参数和结果。
尽量避免使用全局变量。
使用全局变量和静态本地变量的函数是不可重入的,是线程不安全的。

#include <stdio.h>
#include <stdlib.h>
void print_array(int arr[],int n){
    for(int i=0;i<n;++i){
        printf("%d ",arr[i]);
    }
    printf("\n");
}
int* scanf_array(int* n){
    scanf("%d",n);
    int* arr = (int*)malloc(*n*sizeof(int));
    for(int i=0;i<*n;++i){
        scanf("%d",&arr[i]);
    }
    return arr;
}
int main(){
    int n;
    int *arr = scanf_array(&n);
    print_array(arr,n);
    free(arr);
}
上一篇下一篇

猜你喜欢

热点阅读