战国无双-策略国战活动站

C语言教程(四)变量 – 沛旗的博客

- 联盟学院

本文最后更新于 466天前,其中的信息可能已经有所发展或是发生改变。

1. 概述

C语言中,变量是个很重要的概念,前面的章节里很多地方都用到了变量,可见变量无处不在。变量是存储数据的一块可操作的内存区域。我们通过变量名就可以引用这块内存区域,可以获取存储于里面的数据(值),且在运行期间值是可以更改的。简言之,变量就是为了存储数据。

2. 变量名

C语言是强类型编译语言,对变量名有严格的规范要求:

变量名只能由大小写字母、数字和下划线“_”组成。

变量名区分大小写;

不能以数字开头;

长度不能超过63个字符;

不能使用关键字和保留字;

注意变量名的书写风格规范。这个没有硬性要求。

下面是一些变量声明的示例:

//有效变量名

short A;

short a;//和A是不同的变量

int a1;

long _b66;

bool is_true;

//无效变量名

int 6a;

int #123;

int a-b;

int int;

3. 变量类型

声明与定义变量必须指定数据类型,否则会报错;每个变量都有特定的数据类型,类型规定了变量存储的占用空间大小和数据类别。关于数据类型,可参考前面的文章:C语言教程(三)数据类型

下面是数据类型使用的例子:

int a;//声明为int类型的变量

short int b;//声明为short int类型的变量

float f;//声明为float类型的变量

4. 变量声明与定义

4.1 变量的声明

声明的作用就是把变量的信息告诉编译器,编译器会为该变量分配内存空间,使用变量说明符extern的情况下,则不会为其分配空间,因为变量是在别的文件中定义过的。

int a;//声明变量a,告诉编译器声明为int类型的变量,编译器开辟2个或4个字节的空间

long l;//声明变量l,告诉编译器声明为long int类型的变量,编译器开辟4个字节的空间

double d;//声明变量d,告诉编译器声明为double类型的变量,编译器开辟8个字节的空间

如果有数据类型相同的变量,则可以一起声明:

int a,b,c;//同时声明a,b,c三个变量,且都是int类型

int a;//等同于上面的int a,b,c;

int b;

int c;

4.2 变量的定义(初始化)

C语言中,对于全局变量和静态变量,变量声明后编译器会给变量初始化为一个默认值:

整型变量:默认值初始化为0;

浮点变量:默认初始化为0.0;

字符类型:默认初始化为’\0’;

指针类型:默认初始化为NULL;

其他高级类型:根据类型成员默认初始化。

局部变量不会初始化为默认值,初始值是未定义的,所以我们要显示地指定一个初始值:

变量的定义就是声明后使用赋值运算符“=”给变量显示地赋初始值,变量的值应和类型一致:

int a;//声明变量a

a = 5;//初始化为5

变量的声明与赋值也可以写在一行:

int a = 5;//等同于下面的赋值

int a;

a = 5;

和变量声明一样,对多个相同类型变量写在同一行赋值:

int a,b;

a = b = 5;

int a = 3,b = 5;//在一行赋值

5. 变量的分类(作用域)

在C语言中,根据变量定义的位置不同,可分为全局变量、局部变量。而变量的作用域就是变量的有效范围,它表示了变量的可见范围和声明周期。

5.1 全局变量

全局变量是指在函数外部定义的变量,存储在静态存储区,从定义的位置开始到整个程序结束,都是有效的,而且可以被其他任何函数访问,常用于共享数据,下面是一个全局变量的示例:

#include

int a = 5;//定义全局变量

int main(void){

printf("%d\n",a);//在main函数中访问

}

5.2 局部变量

局部变量通常定义在函数体内或者代码块中,一般在函数内部、代码块中或者for循环块作用域中使用,其他函数无法访问,所以局部变量的作用域就是当前的函数或者代码块,随着函数的运行时期而存在。

int main(void){

int a = 1;

if(a == 1){//if代码块

int b = 2;

}

printf("%d\n",a);//输出1

printf("%d\n",b);报错,找不到变量b

}

代码块还可以嵌套,就是代码块包含代码块,这就形成了多层作用域,内层的代码块可以使用外层代码块定义的变量,而外层代码块则不能使用内层代码块的变量,而且还要遵循就近原则,即如果变量名重复,则内层代码块的变量会覆盖外层代码块的变量。

int a = 1;

if(a == 1){

int b = 2;

printf("%d\n",c);//报错

if(b == 2){

int b = 3;

int c = 4;

printf("%d\n",a);//输出1

printf("%d\n",b);//b重复变量名,读取当前代码块中的b,输出3

}

}

C语言中,静态变量分为局部静态变量和全局静态变量,都存储在全局静态存储区,也是编译时就分配空间。静态变量的生命周期也与整个程序的运行周期相同。C语言提供了static关键字来定义静态变量。

全局静态变量,作用域仅限于当前的源文件内部,在其他源文件中是访问不到的

6. 变量说明符

变量说明符就是在变量类型前面添加特定的一个说明符,作为变量的附加信息,可以改变变量的行为和方式。

6.1 static说明符

C语言中规定,使用static关键字可以声明静态变量,静态变量又分为全局静态变量和局部静态变量,都存放于全局静态存储区,在编译时就会为变量分配内存空间,生命周期同整个程序的执行而存在。

全局静态变量,作用域仅限于当前的源文件内部,只能在当前文件使用,在其他源文件中是访问不到的;如果没有显式初始化,编译器则会提供默认值。

局部静态变量,作用域在函数内部定义,函数首次被调用时进行初始化,并在函数调用期间保留变量值,函数调用结束后不会被销毁,下次调用时可以继续使用,编译器也会提供默认值。

static int a = 1;//声明全局静态变量

int main(void){

static int b = 2;//静态局部变量

}

6.2 const说明符

const说明符用于修饰某个变量为(伪)常量,它是只读的,不能被修改。如果更改变量值的话,编译器会报错。

const float f = 3.14f;//只读

f = 3;//报错

const修饰数组时,数组成员的值不能修改,数组的内容在后面章节会讲到

const int arr[] = {1, 2, 3};

arr[0] = 1; // 报错

const修饰指针变量时,有两种表示形式,如果const说明符在指针操作符*前面,表示指针指向的值不可以修改,称为常量指针;如果const说明符在指针操作符*后面,指针本身就是个常量,表示指针本身的值(包含的地址)不可以修改,而不是指针指向的那个值,也称为指针常量。

//const在*前面,常量指针

int const * a;//*a不能更改

const int * a;//和上面的写法一样

//const在*后面,指针常量

int* const a;//a不能更改

6.3 extern说明符

extern说明符用于变量共享,给变量加上extern说明符,就是通知编译器在其他文件中寻找该变量或者函数的定义,可以在多个文件中共享。在使用了extern说明符后,编译器不会再为该变量分配内存了。

带extern说明符的变量声明是无效的,这是为了防止对同一个变量进行初始化,而且同时初始化也会失效,其实extern也相当于引入的意思。

extern int a;//带有extern说明符的变量,在其他文件中已经定义,不必分配内存

extern也同样适用于函数,在一个文件中使用另一个文件中定义的函数:

extern void func();//在其他文件中定义

6.4 register说明符

register修饰的变量是寄存器变量,就是告诉编译器把该变量存放于寄存器中,但是这不是强制性的,编译器可以忽略这个register说明符,而且它的作用域只能在代码块中,因为变量要存放于寄存器中,因此也不会有内存地址。如果将数组设置为register类型,则整个数组及其成员都不能获取地址。

register int a;//这是一个寄存器变量

register int a[] = {1,2,3,4,5};//这是一个寄存器数组

int *p = &a;//没有内存地址,获取失败,编译器报错

int p =a;//报错,没有地址

7. 小结

变量是为了更方便地存储数据;

C语言规定对变量名有命名规范,书写风格也尽量遵守;

声明变量必须指定数据类型,否则会报错;

变量分为全局变量和局部变量,全局变量默认值会为0,而局部变量则是未定义;

常用的变量说明符有static、const、extern、register,此外还有auto、volatile、restrict等,很少用到。

土豆片敷脸的正确方法
淘宝如何找优惠券?如何使用?