C语言常量 变量与作用域

一、常量与符号常量

在这里插入图片描述

1.整型常量

以下是合法的整型常量表示形式:
256,-75,0(十进制整型常量)
0237,045,0621(八进制整型常量,用数字0作前导)
0x28AF,0xED4(十六进制整型常量,用数字0与x作前导)435L,350L(长整型常量)
不合法的整型常量举例如下:
096(9非八进制数码)
48EA(十六进制数缺前导字符0x)
0xK(K非十六进制计数字符)

2.实型常量

实型常量只能用十进制形式表示,不能用八进制和十六进制形式表示。如:28.76,564.03,2.34E+8,15.78E-2都是合法的实型常量,而6.4E+4.8,E9,E-7都是不合法的实型常量。

3.字符常量

‘x’,‘+’,‘\n’,'\101’都是合法的字符常量。

4.字符串常量

" changsha","central south university " 和 "+++? ab"都是合法的字符串常量。

const

const定义常量在C语言中,可以使用const来定义一个常量。常量的定义与变量的定义很相似,只需在变量名前加上const即可,如下所示。

int const a;

以上语句定义了a为一个整数常量。既然a的值不能被修改,如何让a拥有一个值呢?这里一般有两种方法,
其一,是在定义时对它进行初始化,如下所示。

const int a=10;

其二,在函数中声明为const的形参在函数被调用时会得到实参的值。

int fun(const int a)

在这里需要着重讲解的是const涉及指针变量的情况,先看两个const定义。

const int*a;
int*const a;

在第一条语句中,const用来修饰指针a所指向的对象,也就是说我们无法通过指针a来修改其指向的对象的值。但是a这个指针本身的值(地址)是可以改变的,即可以指向其他对象。
与此相反,在第二条语句中,const修饰的是指针a。因此,该指针本身(地址)的值是不可改变的,而该指针所指向的对象的值是可以改变的。

define

define实际是一个预处理指令,其实际的用途远大于定义常量这一功能。在这里,首先讲解define定义常量的基本用法
使用define定义常量实际是进行符号替换,其定义方法为
#define符号名替换列表符号名必须符合标识符命名规则。替换列表可以是任意字符序列,如数字、字符、字符串、表达式等,例如:

#define MSG"I'm Antigloss!"/*后面的所有MSG都会被替换为“I'm Antigloss!”*/
#define SUM 99/*后面的所有SUM都会被替换为99*/
#define BEEP"\a"/*后面的所有BEEP都会被替换为“\a”*/

习惯上,人们用大写字母来命名符号名,而用小写字母来命名变量。

处理指令#define的最后面没有分号“;”,千万不要画蛇添足!

一旦标识符定义成一个常量后,以后在程序处理时,凡是碰到了某个标识符,都将替换成对应的常量。

二.变量与变量定义

变量是以某标识符为名字,其值是可以改变的量。它是以下母或下划线开头的一串字母。数字或下划线构成的序列,最长为1~32个字符。

命名规则

  1. 变量名以英文字母开头。
  2. 变量名中的字母是区分大小写的。
  3. 变量名不能是关键字。
  4. 变量名中不能包含空格、标点符号和类型说明符。

注意:变量名6ab、4x-y、xy·2a、A7+B2都是不合法的,因为它们不符合标识符的组成原则。

实际开发中变量的命名最好见名知意

在C语言程序中,所有的变量必须加以说明,没有任何隐含的变量。变量说明主要是指变量代表计算机内存中的某一存储空间,这个存储空间可以存放不同的数据。出变量的名称,确定变量的数据类型。

在C语言程序中,变量必须“先定义、后使用”。

1.变量定义语句

变量可以在程序的三种地方定义:函数内部、所有函数的外部和函数的参数定义中。由此定义的变量对应地称为局部变量、全程变量和形式参数。例如:

int i,j,k;/*定义三个整型变量i,j,k*/
float x1,y1;/*定义两个单精度型变量x1,y1*/
char profit, loss;/*定义了两个字符型变量profit,loss*/

变量名在定义时可以赋初值。例如:

int a=5,b=8,c;
floatex1=6.27,x2,x3=5.94;
char ch='a', kk='A';

在同一程序中变量名不允许被重复定义,如:

int x,y,z;
float a,b,x;/*变量名x被重复定义,不允许*/

凡未被定义的标识符,不得作为变量名使用。如:

int teacher;

若程序中错将teacher打成teacher,出现:

tcacher=80;

编译将查出teacher未定义。
每一变量被定义成某一类型,编译时将据此为其分配相应长度的存储单元。

2.变量赋初值

变量使用“=”赋初值,必须保证“="右边的常量(或表达式的值)与“=”左边的变量类型一致。例如:

intx=3.2E5,a=15.6;

变量赋值类型不一致将引起错误。
另外,定义变量时,变量不能连续赋初值。

int a=b=c=24.5;/*非法赋值*/

typedef

typedef是C语言的关键字,其作用是为一种数据类型定义一个新名字。这里的数据类型包括内部数据类型(如int、char等)和自定义的数据类型(如struct等)。
其基本用法如下所示。

typedef 数据类型 自定义数据类型

例如,用户可以使用以下语句。

typedef unsigned long unit32 ;

这样,就把标识符unit32声明为无符号长整型的类型了。之后,用户就可以用它来定义变量。

uint32 a;

此句等价于:

unsigned long a;

在大型程序开发中,typedef的应用非常广泛。目的有两点,一是给变量一个易记且意义明确的新名样字,二是简化一些比较复杂的类型声明。

三.作用域

变量的作用域定义:程序中可以访问一个指示符的一个或多个区域,即变量出现的有效区域,决定了程序的哪些部分通过变量名来访问变量。一个变量根据其作用域的范围可以分为函数原型作用域、局部变量和全局变量。

1.函数原型作用域

函数原型中的参数,其作用域始于“(”,结束于“)"。
设有下列原型声明:

double Area(double radius);

radius的作用域仅在于此,不能用于程序正文其他地方。

for (int i=0; i<10; i++)

i 的作用域仅在于此,不能用于程序正文其他地方。

2.局部变量

在函数内部定义的变量称为局部变量。局部变量仅能被定义该变量的模块内部的语句所访问。换言之,局部变量在自己的代码模块之外是不可见的。

模块以左花括号"{“开始,以右花括号”}"结束。

对于局部变量,要了解的重要规则是,它们仅存在于定义该变量的执行代码块中,即局部变量在进入模块时生成(压入堆栈),在退出模块时消亡(弹出堆栈)。定义局部变量的最常见的代码块是函数,例如:

void func1()
{
/*在funci中定义的局部变量x*/
	int x;
	x=10;
	printf("%d",x);
}
void func2()
{
/*在func2中定义的局部变量x*/
	int x;
	x=2007;
	printf("%d",x);
}

输出结果:

x=10;
x=2007;

整数变量x被定义了两次,一次在funel中,另一次在func2中。funel和func2中的x互不相关,原因是每个x作为局部变量仅在被定义的模块内可见。
局部变量是在函数内定义的变量。其作用域仅限于函数内,在函数内才能引用,即可以对它赋值或取值。在作用域以外,使用它们是非法的。例如:

#include<studio.h
void f1()
{
	int t=2;
	a*=t:
	b/=t;/*f1中引用main()中的变量a和b是非法的*/
}

void main()
{
	int a,b;
	 /*输入两个数,分别存入变量a和b中*/
	printf("Enter a,b:");
	scant("%d,%d",&a,&b);
	/*调用函数f1()*/
	f1(); 
	printf("a=%d,b=%d",a,b);
}

编译提示以下错误:

errorC2065 :"a":未声明的标识符
errorC2065 :"b":未声明的标识符

要注意的是,在一个函数内部可以在复合语句中定义变量,这些复合语句成为“分程序”或“程序块”,如下所示。

void funclo
{
/*在funci中定义的局部变量x*/
	int x;
	x=10;
	{
	/*定义程序块内部的变量*/
		int c;
	/*变量c只在这两个括号内有效*/
		c=a+b;
	}
}

在上述的例子中,变量c只在最近的程序块中有效,离开该程序块就无效,并释放内存单元。

3.全局变量

全局变量与局部变量不同,全局变量贯穿整个程序,它的作用域为源文件,可被源文件中的任何一个函数使用。它们在整个程序执行期间保持有效。

#include <stdio.h>
/*定义全局变量*/
int a,b;
void f1()
{
	int t1,t2;
	/*使用全局变量在main()中的赋值*/
	t1=a*2;
	t2=b*3;
	/*改变b的值*/
	b=100;
	printf("t1=%d,t2=%d\n",t1,t2);
}
void main()
{
/*全局变量赋值*/
	a=2; b=4;
	/*调用 f1()*/
	f1();
	printf("a=%d,b=%d",a,b);
	system("pause");
}

输出结果

t1=4,t2=12;
a=2,b=100;

在f1()中对全局变量b的赋值保留下来,在main()中输出。

在同一源文件中,允许全局变量和局部变量同名。在局部变量的作用域内,全局变量不起作用。因此,若在该函数中想要使用全局变量,则不能再定义一个同名的局部变量。
如有以下代码:

#include<stdio.h>
/*定义全局变量i并赋初值为5*/
inti=5;
int main()
{
/*定义局部变量i,并未赋初值,i的值不确定,由编译器自行给出*/
	int i;
/*打印出i的值,查看在此处的i是全局变量还是局部变量*/
	if(i!=5)
	{
		printf("it is localn");
		printf("iis%d\n",i);
	}
	return O;
}

程序执行结果如下:

it is local
iis 134518324

可以看到,i的值并不是全局变量所赋的初值,而是局部变量的值。

由于全局变量从定义之处起,所有的函数都可以引用它。所以,全局变量的命名最好取有特殊含义的标识符,防止在某个函数中,在不经意中改变了它的值,使整个程序的结果出现错误。

4.外部变量的使用 extern

前面已经介绍了全局变量的作用域是所在的整个文件,而一个文件中的全局变量的作用域还可以扩展到其他文件。即一个文件中的全局变量可以在另一个文件中作为外部变量使用。某个文件中引用另一个文件中的全局变量,只要用extern声明,说明这个变量是在其他文件中已经定义过的外部变量。那么,在该文件中不会为外部变量分配内存。C语言中,用extern说明一个外部变量。语句格式如下:

extern 类型说明符 外部变量名;

例如:假如程序模块file1.c中定义了全局变量

int students;

如果在另一个程序模块file2.c中的函数fun()中,需要使用students变量

fun1()
{
extern int students;
}

这里,“extern int students;”是外部变量说明语句。
这样,通过外部变量说明语句,全局变量的作用域可以扩展到另一个模块文件的fun1()中,如果外部变量说明语句写在文件的头部,就可在该文件的任何函数内对students进行操作。

extern int students;
funl()
{students=30;}
fun2()
{students+=21;}

在funl和fun2中都引用了外部变量students。

全局变量就是外部变量。前面分别介绍全局变量和外部变量,只是为了突出作用域和作用域扩展的问题。从定义变量的角度看,定义全局变量和外部变量是同一个概念。完整的定义形式是:

[extern] 类型说明符变量名,变量名,….

[extern]可以省略。它是在函数外部定义的变量。它不属于哪一个函数,它属于一个源程序文件。

int a,b;
等效于:
extern int a,b;
  • 0
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值