C语言详解(2)变量的实质

来源:互联网 发布:淘宝内部卷 编辑:程序博客网 时间:2024/05/29 14:27

变量


 关于C语言详解系列blog的目录:http://blog.csdn.net/snake_lp/article/details/78630717


一、概述

变量实际上是一段连续的存储空间的别名。一个变量名就是代表内存某一段地址的数据。程序中通过变量来申请存储空间,并将这段存储空间命名为变量名。程序员通过变量的地址就可以使用这段存储空间的内容了。

数据类型是模板,变量是实体。变量所占用的存储空间就是以定义变量的数据类型的内存大小为step的。

变量的实质就是一块可以被用户修改的内存数据,主要强调的是数据可以修改,所以称之为变量。

 

变量的两个常用语:

1、  作用域:指的是变量作用的范围。在哪个范围变量是可用的,有效的;

2、  生命周期:指的是变量存在的时间长度。从创建到销毁的时间段,即该变量占用该段内存的时间长度。

 

二、变量的分类

从作用域分的话,可以分为全局变量、局部变量。

1.      全局变量

全局变量就是在函数之外申明的变量。一般情况下,全局变量在声明文件的任何地方都是有效的。但是也存在例外,那就是全局变量和局部变量重名的时候,局部变量的优先级高,在局部变量的作用区域内全局变量就不可见了。

如下列代码:

#include <stdio.h> int val1 = 0; /*全局变量*/int val2 = 0; void func(void){int val1 = 8;/*局部变量,仅仅在func函数中有效*/printf("[func] val1 =%d\n",val1);} int main(void){int val1 = 5;/*局部变量*/val2 = 9;printf("[main] val1 =%d,val2 = %d\n",val1,val2);func();return 0;}

运行结果为:

从上述代码的运行结果可以看出全局变量的作用范围。

这种变量的定义方式,在C语言的语法上没有任何的问题,但是在实际项目工程中需要避免这种现象。局部变量和全局变量不要使用同一个变量名字,这样的做法会降低程序的可读性。

 

对于全局变量的作用范围,应该和编译器有关系的。一个全局变量有的编译器认为这个变量是在工程的全部文件中可见;有的编译器认为是只在本文件中可见。由于C语言设计的中心思想是:未声明,不可用。所以为了提高代码的移植性,请使用以下的做法:

1.如果需要跨文件使用变量,请使用extern来显性修饰;在一个文件中定义变量int val;在需要使用的文件中使用extern声明变量extern int val;

2.如果仅仅在当前文件中使用,请使用static来现象修饰static int val;。

 

2.      局部变量

在代码示例中,main函数和func函数中val1就是局部变量。更直接的说,在代码块(以{}包括的代码)中定义的变量就是局部变量。它的作用域仅仅在代码块中,如果在其他地方使用,在编译的时候,就会报错[变量未定义]。局部变量在函数调用时由系统自动分配存储区(堆栈),在不同的函数中,堆栈的区域是不一样的,所以在不同的函数中定义的局部变量可以使用相同的名字。比如说函数的形参,函数内部定义的变量都是局部变量,在函数调用结束之后,局部变量就会销毁。

 

从生命周期来划分的话,可以分为静态变量、动态变量、堆变量。

1.      静态变量(static variable)

全局变量和使用static修饰的局部变量都具有静态的存储期。它们从程序的开始到程序的结束一直都存在的,所以存称之为静态变量。静态变量在编译的时候就分配了内存空间并且进行了赋值的操作,所以在程序运行时它就已经存在了初始化值。以后每次调用函数时,不在需要重新赋值了而是保留上一次函数调用结束时候的数值。

如果在定义静态变量时不对它进行赋值操作,在编译的时候编译器会自动赋值为0(对数值型变量)或者空字符(对字符型变量)。

需要注意的是,静态局部变量在函数调用时仍然存在,但是对其他函数不可见,即其他函数是不能使用它的。

 

2.      动态变量(auto variable)

没有被指定static类型的局部变量和寄存器变量(register variiable)都是自动变量。函数的形参以及代码中定义的变量都属于自动变量。这是C语言中应用最广泛的一种变量,这类变量是栈分配的,是动态分配存储空间的。

以函数的形参为例:当调用该函数时,为形参分配存储空间,当函数调用结束时,就自动释放这些存储空间。对代码中定义的变量(包含函数中定义的变量),当执行到变量申明语句时,系统会为这些自动变量分配空间,当程序流程离开代码块(函数),这些变量就会自动销毁,其占用的内存空间就会被释放。

自动变量(即动态局部变量)属于动态存储的类别,存储在动态存储空间(而不是在静态存储区空间),函数调用时分配空间,调用结束就释放。

自动变量如果不赋初值的话,则它的值就是一个不确定的随机值。这是由于每次调用函数结束时存储单元就释放,下次调用时又重新分配存储空间,而所分配的存储空间也是不确定的,故变量的值就无法确定。

 

3.      堆变量

通过malloc()函数分配内存空间的变量被存放在堆中,故称之为堆变量。并且这类的“堆”和数据结构中的堆没有任何的连续。是硬件平台存储的位置和方式。

堆变量需要手动分配内存,也需要手动释放内存,也就是说它从创建时起就一直存在直到使用free()函数释放位置。当然,建议在程序设计中需要做到:谁创建,谁释放。

         在嵌入式开发中一般尽量少是使用堆变量,如果没有控制好,很容易造成内存占用过大或者未释放溢出的问题,另外现在的MCU的内存资源基本上可以满足我们的开销。

 

原创粉丝点击