嵌入式Linux C语言: 7.对象作用域与生存周期

嵌入式Linux C语言: 7.对象作用域与生存周期

1. 作用域

作用域就是一个对象在怎样的范围内起作用

对象主要包括以下三种:
变量(包含数组) 作用域
函数      作用域
类型      作用域

一个C语言程序(工程), 可以包含多个.c/.h文件

作用域可以分为三大类:

  1. 整个工程作用域: 在工程的所有文件中, 都有作用
  2. 本文件作用域: 只在本文件(.c/.h)中起作用
  3. 函数作用域/代码块作用域: 仅在{ }中起作用

变量的作用域
根据变量的作用域不同, 分为如下几种变量
a、全局变量: 作用域 整个工程起作用
 定义在函数外的变量

 1.c
  int a=3; //全局变量
 2.c
  在2.c中可以使用1.c的变量a
  需要外部声明
  extern int a;//声明外部变量

b、static 修饰的全局变量
 定义在函数外面的变量, 只不过在前面加了一个static
 static修饰的全局变量, 会使得被修饰的全局变量的作用域发生改变, 变成仅在本文件中有效

 1.c
  static int a= 1; //static 修饰的全局变量作用域发生改变, 变成仅在本文件中有效
 2.c
  想要在2.c中去使用1.c中的变量a, 不能使用
  extern int a; //外部声明没有用

c、局部变量
 定义在{ }内的变量, 局部变量
 局部变量的作用域: 代码块作用域/函数作用域
 也就是说局部变量仅在定义它的那个{ }中起作用

 func()
 {
  int a=5;
  if(1)
  {
   int b=6;*
   printf(“%d/n”, a); // 5
   printf(“%d\n”, b); // 6
  }
  printf(“%d/n”, a); // 5
  printf(“%d\n”, b); // ERROR undefined 仅在定义b的{ }中起作用
 }

函数的作用域
a、整个工程作用域

1.c
	static int sum(int a, int b) //函数本来的作用域是整个工程作用域, static修饰函数是, 改变函数的作用域, 比那城仅在本文件中生效
	{
		return a+b;
	}
2.c
在2.c中调用sum, 需要在2.c中声明1.c中这个函数sum
	static int sum(int a, int b); //外部声明ERROR 
	或
	int sum(int, int); //ERROR
	//声明没有问题, 原因是1.c中的sum函数被static修饰, 函数的作用域发生改变
	int main()
	{
		int a=3, b=4;
		printf("%d\n", sum(a, b)); //ERROR sum函数的作用域仅在1.c中生效
	}

函数本来的作用域是整个工程作用域, static修饰函数时, 改变了函数的作用域, 变成仅在本文件中生效

类型的作用域
a、在本文件的作用域

1.c
	struct test
	{
		int a;
		char c;
	};
在1.c中声明了一个新的类型, 是一个结构体类型, 类型名为: struct test
定义一个上面类型的变量: 变量类型 变量名;
	struct test a; //a就是一个结构体变量
2.c
	在2.c中不可以使用1.c中的 strcut test 类型

b、代码块作用域

func()
{
	struct test
	{
		int a;
		char c;
	}; //仅在定义它的{ }内可见
}

typedef int int32_t; //仅在本文件中生效
int32_t 就是 int类型
typedef 声明一个新类型
#include <stdio.h>

int main()
{
	int a=6; 
	if(1)
	{
		int a=7;
		printf("%d\n", a); //7
	}
	printf("%d\n" , a); //6
	return 0;
}

在此,对于作用域问题, 赠大家一首小诗:
同名不要紧,
只要域不同。
具体是哪个,
就近往上找。

2. 生存期

生存期就是一个对象从生到死的生存期间

生存期有三种:

  1. 随文件系统持续性:
     只要文件系统存在, 那么这个对象就一直存在。
     如: 代码(代码文件)
  2. 随程序持续性/随进程持续性:
     进程: 一个正在运行的程序
     一个对象, 进程启动时, 它就存在, 并且一直持续到进程退出(消亡)
     进程启动时, 就会给那些随进程持续性的对象分配地址空间并且这个空间一直持续到进行结束才会被操作系统收回

随进程持续性的对象
 全局变量
 函数
 static 修饰的全局变量

  1. 随代码块持续性:
     指一个对象, 在运行它所属的代码块时, 才分配空间给它, 并且当代码块执行完毕时, 它的空间就会自动收回

随代码块持续性的对象:
 普通的全局变量

初始化, 初始化语句
 在定义一个对象时, 给这个对象赋值的语句就是初始化语句
 初始化: 在给对象跟哦诶空间时才会赋值的值

 初始化语句只会在给对象分配空间的时候, 执行一次

void f()
{
	int a=1; // 生存期: 随代码块持续性
	a++;
	printf("%d\n", a);
}

int main()
{
	f(); // 8
	f(); // 8
	return 0;
}


-----------------------------------------
void f()
{
	static int a=1; // 生存期: 随进程持续性, 并且初始化语句只在分配空间时执行一次
	a++;
	printf("%d\n", a);
}

int main()
{
	f(); // 8
	f(); // 9
	return 0;
}

局部变量: 随代码块持续性
当 static 修饰局部变量时, 局部变量的生存期变为随进程持续性

static 的作用:
 static在C语言中只有两个作用:
  1. static 用于修饰全局变量或函数时, 被修饰的全局变量或函数的作用域变为仅在本文件中有效 (作用域发生改变)
  2. static 用于修饰局部变量时, 被修饰的剧变量的生存期变为随进程持续性 (生存期发生改变)

Linux 中保存的内容是分段的
分段
 .text  存放代码(代码段)  进程持续性
 .data  初始化的全局变量和静态变量  数据段 进程持续性
 .bss  没有初始化的全局变量和静态变量  数据段 进程持续性
 …
 堆  动态内存空间  malloc 和C++中的new相同
 栈(每一个堆和栈存储的内容不同)  局部变量 代码

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值