文章目录
一、常量与符号常量
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个字符。
命名规则
- 变量名以英文字母开头。
- 变量名中的字母是区分大小写的。
- 变量名不能是关键字。
- 变量名中不能包含空格、标点符号和类型说明符。
注意:变量名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;