内容导航|Navigation
C语言是结构式语言。结构式语言的显著特点是代码及数据的分隔化,即程序的各个部分除了必要的信息交流外彼此独立。这种结构化方式可使程序层次清晰,便于使用、维护以及调试。C语言是以函数形式提供给用户的,这些函数可方便地调用,并具有多种表达式语句、条件语句控制程序流向,从而使程序完全结构化。
学习目标|Objective
一个C语言源程序,是由一个或多个函数定义顺序组成的,其中必须有一个函数名为main的主函数。C语言源程序的主要组成部分有:编译预处理命令、注释和声明。而主函数则是被编译程序翻译成一个机器语言形式的主程序段,任何其他函数都将被编译程序翻译成机器语言形式的子程序段。
通过对第1章的学习,我们总结出了C语言源程序的几个特点:
(1)一个C语言源程序可以由一个或多个源文件组成。
(2)每个源文件可由一个或多个函数组成。
(3)一个源程序不论由多少个文件组成,都有一个且只能有一个main()函数,即主函数。
(4)源程序中可以有预处理命令(“include”命令仅为其中的一种),预处理命令通常应放在源文件或源程序的最前面。
(5)每一个说明、每一个语句都必须以分号结尾,预处理命令除外。
(6)标识符和关键字之间必须至少加一个空格以示间隔。若已有明显的间隔符,可以不用再添加。
C语言源程序中的函数并非数学中那些高深莫测的函数,它只是完成特定数据处理任务,功能上独立的一个程序段而已。
任何一个函数定义都是由函数首部和函数体构成。函数体必须用大括号“{”和“}”括起来,函数体必须紧接在函数首部之后。格式如下:
函数定义=函数首部+函数体 int main(void)() // 函数首部 { // 函数体 …… return 0; }
C语言源程序中,函数体的成分是由0条或多条变量组成的定义序列;1条或多条语句顺序组成的语句序列。格式如下:
函数体的主要成分:变量定义序列+语句序列 int r=5; int f=3; int s; // 变量定义序列 s=r*f; // 语句序列
提示
变量定义序列和语句序列都是由分号“;”结尾的。
C语言程序中的变量定义序列,被编译程序转变为机器语言程序中,存放多个数据的内存单元地址;而C语言源程序函数体中的语句序列,则被编译程序翻译成对这些内存单元中的数据,进行运算处理的机器指令序列。
【例2-1】编写一段程序,实现两个数相乘的功能。(源代码\ch02\2-1)
运行上述程序,结果如图2-1所示。
图2-1 变量定义序列
【代码解析】
main()是主函数的函数名,表示这是一个主函数,也是函数的首部。而函数体就是大括号里面的一系列语句。定义的三个整型变量r、s、f构成了一组变量序列,最后通过语句序列(s=r*f)输出需要的答案。
编码是一种艺术,它不仅仅是为了完成某一个特定的功能而堆砌的一些英文字符,而且是编程人员综合素质的体现。程序的版式虽然不会影响程序的功能,但会影响可读性。程序的版式追求清晰、美观,是程序风格的重要构成因素。
程序版式的具体要求如下:
(1)程序结构清晰,简单易懂,单个函数的程序行数不得超过100行。
(2)每个源文件,都有头文件说明。
(3)程序块要采用缩进风格编写,每次缩进一个Tab键。
(4)空行起着分隔程序段落的作用。空行得体将使程序的布局更加清晰。空行不会浪费内存,虽然打印含有空行的程序是会多消耗一些纸张,但是值得的。所以不要舍不得用空行。相对独立的程序块之间、变量说明之后必须加空行。
(5)一行代码只做一件事情。如只定一个变量或只写一条语句,这样的代码容易阅读,并且方便于写注释。
(6)程序的分界符“{”和“}”应独占一行并且位于同一列,同时要与引用的语句左对齐。
(7)“{ }”之内的代码块在“{”右边数格处左对齐。
(8)if、for、while、do等语句自占一行,执行语句不得紧跟其后。不论执行语句有多少都要加“{ }”。这样可以防止书写失误。
(9)代码行不要过长,否则眼睛看不过来,也不便于打印。
没有一种命名规则可以让所有的程序员赞同。程序设计教科书一般都不指定命名规则。命名规则对软件产品而言并不是“成败攸关”的事,所以不要花太多精力试图发明世界上最好的命名规则。而应制定一种令大多数项目成员满意的命名规则,并在项目中贯彻实施。
比较著名的命名规则当推Microsoft公司的“匈牙利”法,该命名规则的主要思想是在变量和函数名中加入前缀以增进人们对程序的理解。例如所有的字符变量均以“ch”为前缀,若是指针变量则追加前缀“p”。如果一个变量由“ppch”开头,则表明它是指向字符指针的指针。
以下给出一些Windows应用软件开发的命名规则:
(1)变量和参数用小写字母开头的单词组合而成。
(2)常量全用大写的字母,用下划线分割单词。
(3)静态变量前加前缀s_(表示static)。
(4)如果不得已需要全局变量,则使全局变量加前缀g_(表示global)。
(5)为了防止某一软件库中的一些标识符和其他软件库中的标识符冲突,可以为各种标识符加上能反映软件性质的前缀。例如三维图形标准OpenGL的所有库函数均以gl开头,所有常量(或宏定义)均以GL开头。
C语言编码时的正确性与容错要求如下:
(1)程序首先是正确的,其次是优美。
(2)无法证明你的程序没有错误,因此在编写完一段程序后。应先回头检查。
(3)改一个错误时可能产生新的错误,因此在修改前首先要考虑对其他程序的影响。
(4)所有变量在调用前必须被初始化。
(5)对所有的用户输入,必须进行合法性检查。
(6)不要比较浮点数是否相等。
例如:
10.0*0.1 == 1.0 //不可靠
C程序的执行部分是由语句组成的,程序的功能也是由执行语句实现的。C语言中的语句基本可以分为五大类:表达式语句、函数调用语句、控制语句、复合语句以及空语句。
表达式语句由表达式加上分号“;”组成。其语法格式为:
表达式;
例如:
x=y+z;z=100 // 赋值语句 y+z; // 加法运算语句,但计算结果不能保留,无实际意义 i++; // 先引用变量i,然后变量i进行自加1运算 ++i; // 变量i先进行自加1运算,然后对变量i进行引用
提示
执行表达式语句就是计算表达式的值。
函数调用语句由函数名、实际参数加上分号“;”组成。其一般形式为:
函数名(实际参数表);
执行函数语句就是调用函数体并把实际参数赋予函数定义中的形式参数,然后执行被调函数体中的语句,求取函数值。
例如,调用库函数printf(),就相当于一个函数语句:
printf("My first C program!");
通过调用函数printf(),来实现输出字符串的功能。
控制语句是由特定的语句定义符组成,使用控制语句可实现程序的各种结构方式,从而实现对程序流程的控制。
C语言有九种控制语句。可分成以下三类:
(1)条件判断语句:if语句、switch语句。
(2)循环执行语句:do while语句、while语句、for语句。
(3)转向语句:break语句、goto语句(此语句尽量少用,因为这不利结构化程序设计,滥用它会使程序流程无规律、可读性差)、continue语句、return语句。
把多个语句用括号“{ }”括起来组成的一个语句称复合语句。
例如,以下为一条复合语句:
{ k=i+j; a=b+c; printf("%d%d\n",k,a); }
复合语句内的各条语句都必须以分号“;”结尾;此外,在括号“}”外不能加分号。
提示
复合语句在程序中属于一条语句,不能将它看为多条语句。
空语句是由分号“;”组成,并且是什么也不执行的语句,在程序中空语句可用来作空循环体。
例如:
int x=4; ++x; ; printf("%d",x);
第三行的语句就是一条空语句,程序执行到此时什么都不会做,继续向下执行,空语句不会影响到程序的功能以及执行的顺序。
在C语言中,输入与输出功能是通过调用标准库函数中的函数来实现的。在函数库中包含一系列标准输入输出函数,有格式化输入输出函数:“printf”,“scanf”;字符输入输出函数:“putchar”,“getchar”;字符串输入输出函数:“puts”,“gets”。
scanf()函数的作用是从输入设备输入若干个任意类型的数据。它的函数原型在头文件<stdio.h>中,C语言是允许在使用scanf()函数之前不包含<stdio.h>文件。scanf()函数最末一个字母f即为“格式”(format)之意。
scanf()函数是C语言提供的标准格式输入函数,用来按照指定的格式输入数据并保存到指定变量的存储地址中去。scanf()函数调用的一般形式为:
scanf ("格式控制字符串",地址列表);
例如:
scanf("%d %c", &a,&b);
该函数主要有如下两个参数:
(1)格式控制字符串:用来指定每个输入项的输入格式。格式控制字符串通常由“%”和格式字符组成,如%d、%c、%f等。它的作用是确定输入数据的格式,格式说明都是由“%”字符开头的。
(2)地址列表:地址列表给出各变量的地址。地址是由地址运算符“&”后跟变量名组成的,例如,&a表示变量a在内存中的地址,其中&是取地址运算符,其作用是求变量的地址。
其地址列表的个数必须与格式字符串中规定字符的个数一样多,各地址之间用“,”分开,且顺序必须一一对应,否则将会出现意想不到的错误信息提示,并且各变量前必须加上“&”,用于指向各变量在内存中的地址。
提示
区分变量的值和变量的地址这两个不同的概念。变量的地址是由C编译系统分配的。用户不必深究具体的地址是多少。
在赋值表达式中给变量赋值,例如:
a=1;
则变量的地址与变量值的关系如下所示:a为变量名,1是变量的值,&a是变量a的地址。
在赋值号左边是变量名,不能写地址。而scanf()函数本质上也属于给变量赋值,但要求必须写变量的地址,如:&a。两者在形式上略有不同。“&”是一个取地址运算符,&a是一个表达式,其作用是求变量的地址。
scanf()函数的格式控制符中也可以有多种规定字符,常见格式控制符如表2-1所示。
表2-1 scanf()函数的格式控制符
scanf()函数格式控制可表示为:
%[*][宽度][长度]类型
其中“[]”中为可省略项,其余各项的意义如下:
(1)符号“*”用于表示输入项在录入后被跳过,不赋予相应的变量。
例如,读入整型变量a,b的值,在输入时跳过第二个录入值:
scanf("%d%*d%d",&a,&b);
假设输入2,3,4,则2被赋予变量a,3被跳过,4被赋予变量b。
【例2-2】编写一段程序,读入整型变量a,b的值,在输入时跳过第二个录入值。(源代码\ch02\2-2)
#include<stdio.h> int main() { int a,b,c; printf("请输入三个数:\n"); scanf("%d %*d %d",&a,&b,&c); printf("a=%d b=%d c=%d\n",a,b,c); return 0; }
运行上述程序,结果如图2-2所示。
图2-2 “*”的使用
【代码解析】
本例用于演示格式控制的不同情况。输入三个数据4,5,6。打印出来会发现,4被赋予变量a,5被跳过,6被赋予变量b,c就是一段杂乱的数据,没有任何意义。
(2)用于指定所录入的数据宽度,它的书写形式为“%n类型”,表示录入一个宽度为n的数据,若输入的数据宽度大于n,则保留n位数据,其余舍去。
例如,输入长度为3的整型数据:
scanf("%3d",&a);
假设输入123456,则实际将123赋予变量a,456被舍去。
例如,输入2个长度为3的整型数据:
scanf("%3d%3d",&a, &b);
假设输入123456,则实际将123赋予变量a,将456赋予变量b。
【例2-3】编写一段程序,通过scanf()读入一串数字,查看打印结果。(源代码\ch02\2-3)
#include<stdio.h> int main() { int a,b; printf("请输入一串数字:\n"); scanf("%3d %2d",&a,&b); printf("a=%d b=%d\n",a,b); return 0; }
运行上述程序,结果如图2-3所示。
图2-3 “%n类型”的使用
【代码解析】
本例用于演示通过scanf()输入函数录入数据,并通过格式控制字符串控制输入的数据格式。“%3d”就是将123赋予变量a,“%2d”将45赋予变量b,67则被舍去。
(3)长度
通常使用字母“l”与字母“h”表示长度格式符,其中字母“l”表示输入长整型数据,如“%ld”“%lo”“%lx”“%lu”,以及double型数据,如“%lf”“%le”;字母“h”表示输入短整型数据,如“%hd”“%ho”“%hx”。
注意:
例如:
scanf ("%d,% d",&a,&b );
不能将上述语句写成:
scanf ("%d,%d",a,b);
例如:
scanf("%3.14f",&x);
此语句是非法的,不能使用此语句输入小数。
例如:
scanf ("a=%d,b=%d",&a,&b);
则键盘输入时应输入:
a=1,b=2;
看似起提示作用,但由于用户看不见程序中的a=和b=,所以实际起不到提示作用。应尽量不写,若需要加提示,在上一行加上“printf("a=,b=");”更好。
printf()函数的作用是向终端输出若干个任意类型的数据。它的函数原型在头文件<stdio.h>中,与格式输入函数scanf()相同,C语言中允许在使用printf()函数之前不包含<stdio.h>文件。
格式化输出函数printf()主要是将标准输入流读入的数据向输出设备进行输出,它的语法形式如下:
printf (格式控制字符串,输出列表);
该函数主要有如下两个参数:
(1)格式控制字符串:用来指定每个输出项的输出格式,格式控制字符串通常由格式说明、转义字符和普通字符组成。
① 普通字符:也称为非格式说明符,按原样输出字符。
例如:
printf("a+b=%d\n",x);
其中,“a+b=”是非格式说明符,执行时按原样输出。
② 转义字符:是以“\”开头的字符,例如“\t”“\n”等。
③ 格式说明:由“%”和格式字符组成,例如%d、%c、%f等用来指定数据的输出格式。格式说明都是由“%”开头,以说明输出数据的类型、形式、长度、小数位数等。例如:
"%d" // 按十进制整型输出 "%ld" // 按十进制长整型输出 "%c" // 按字符型输出
(2)输出列表:是要输出的各项数据,这些数据可以是常量、变量、函数或表达式,其具体类型由格式控制符中的格式字符决定。输出列表的个数必须与格式控制字符串中规定的字符个数一样多,各参数之间用“,”分开,且顺序一一对应,否则将会出现意想不到的错误。
【例2-4】编写程序,输出代码中变量的值。(源代码\ch02\2-4)
#include <stdio.h> int main() { int a=3,b=2,c; printf("a=%d,b=%d\n",a,b); printf("a=%d\n",a,b,c); printf("a=%d,b=%d,c=%d\n",a,b); printf("c=%d\n",c=a+b); printf("a=%d\n",a=a+2); return 0; }
运行上述程序,结果如图2-4所示。
图2-4 输出列表
【代码解析】
本例演示了printf()函数的输出列表。在代码中,第一个printf()函数中输出列表的个数与格式控制字符串中规定的字符个数一样多,所以正确地输出了两个变量a和b的值;第二个printf()函数中输出列表有三个变量a、b、c,格式控制字符串中却只有一个字符a,所以也只输出了一个变量a的值;第三个printf()函数由于缺少输出项,最后就会输出一段没有意义的数据;最后两个printf()函数的输出列表允许是表达式。
C语言提供的printf()函数中使用的格式控制符如表2-2所示。
表2-2 printf()函数的格式控制符
提示
使用格式字符时,除了X、E等有大写形式的,其余格式字符必须使用小写形式,否则会出现错误。
【例2-5】编写程序,分别定义int型、float型以及char型变量,使用相应的输出格式字符将它们输出。(源代码\ch02\2-5)
#include <stdio.h> int main() { int x=5; // 分别定义int、float以及char型变量 float y=3.14; char c='w'; printf("x=%d\n",x); // 使用相应的格式字符输出 printf("y=%f\n",y); printf("c=%c\n",c); return 0; }
运行上述程序,结果如图2-5所示。
图2-5 格式字符
【代码解析】
本例用于演示通过使用不同的格式字符,将相应类型的变量进行输出的操作。代码中首先定义了不同类型的变量,包括int、float以及char型,然后使用%d来输出int型变量数据;使用%f来输出float型变量数据;使用%c来输出char型变量数据。
在输出函数printf()中,格式转换字符一般可以表示为:
%[符号][宽度][.精度]格式字符
其中“[]”中为可省略项,其余各项的意义如下:
(1)通常输出数据都隐含右对齐,如果想实现左对齐,可以在格式控制中的“%”和宽度之间加一个符号“-”。
以输出字符串为例:
printf("%-s","Hello"); // 输出字符串"Hello",并保持左对齐
其中“%-s”表示输出的字符串内容左对齐,若没有“-”符号则右对齐输出。
(2)宽度指的是域宽,也就是对应的输出项输出到设备上时所占的字符数。
以输出字符串为例:
printf("%8s","Hello"); // 输出字符串长度5小于8,则左补3个空格 printf("%2s","Hello"); // 输出字符串长度5大于2,则突破2的限制,全部输出
其中“%ms”表示输出的字符串共占m列,若输出的字符串长度大于m,则突破m限制,将字符串全部输出;若字符串长度小于m,则左补空格。
提示
“%0s”表示输出的字符串若有空位,则用数字“0”进行补位。
例如:
printf("%08s","Hello"); // 表示右对齐输出长度5的"Hello",8为宽度,所以左补3个0
(3)精度用于说明所输出的实型数据的小数位数。它的书写格式为:“%.nf”,表示输出小数位数为n的实型数据。
例如:
float a=5.4321; printf("%.3f\n",a); // 输出float变量a,保留3为小数,则结果为5.432
提示
若将要输出的实数小数点后位数大于所要保留的小数位数,则通过四舍五入后保留;若将要输出的实数小数点后位数小于所要保留的小数位数,则缺位补0。
对于输出精度的情况,还有一种在格式字符前加字母“l”的表示方法:“%ld”,字母“l”的加入表示对于整型,则输出long型;对于实型,则输出double型。
例如:
long a=54321; printf("%ld\n",a); // 输出长整型变量a的值
【例2-6】编写程序,定义float型变量a=5.4321,定义long型变量b=12345678,通过格式控制,输出变量a保留3位小数的形式,输出长整型变量b,输出字符串“program”左端“pro”,并保持左对齐,而左端补空格。(源代码\ch02\2-6)
运行上述程序,结果如图2-6所示。
图2-6 格式控制
【代码解析】
本例用于演示格式控制的不同情况。首先定义float型变量a与long型变量b,使用精度控制输出变量a保留3位小数的形式,结果为5.432,可以发现是经过了四舍五入后的结果;使用“%ld”的形式输出变量b;而“%7.3s”表示右对齐输出内容,“7”表示输出宽度,“.3”表示精度3,在字符串中为截取左端3个字符,所以输出的结果为7个长度,右端为“pro”,左端补4个空格,并使用“|”符号来检验空格。
getchar()函数是字符输入函数,作用是从标准输入设备(键盘)上输入一个字符,在同一时间只能读取一个单一的字符。
getchar()函数的使用语法如下:
getchar();
注意:
(1)使用getchar()函数输入时,都是转换为ASCII码值来存储,所以getchar()函数读取一个字符,返回的是一个整数。
(2)getchar()函数无参数,但括号不能省略。输入数字也必须按字符进行处理。当输入多个字符时,只能接收第一个字符。
而在编写C程序时,通常把输入的字符赋予一个字符变量,使其构成一个赋值语句,语法如下:
char x ; //定义字符变量x x = getchar( ); // 从键盘输入一个字符,然后将字符的值赋给变量x
提示
同putchar()函数一样,使用getchar()函数时,首先要添加头文件“#include <stdio.h>”。
【例2-7】编写程序,使用getchar()函数通过输入端输入一个字符,然后通过putchar()函数将此字符输出。(源代码\ch02\2-7)
#include <stdio.h> int main() { char c; // 定义字符变量 printf("请输入一个字符:"); c=getchar(); // 从键盘输入单个字符B给c字符变量 putchar(c); // 输出c字符变量的值 putchar('\n'); return 0; }
运行上述程序,结果如图2-7所示。
图2-7 getchar()函数
【代码解析】
本例用于演示如何使用getchar()函数输入一个字符。首先定义一个char型变量c,用于存放要输入的字符,然后通过printf()函数输出一行提示信息,接着使用getchar()函数,通过输入端输入一个字符并赋予变量c,然后通过putchar()函数输出变量c。
在使用getchar()函数时,如果需要连续地输入两个字符,那么在输入第二个字符前需要清除缓冲区,或者使用getchar()函数获取回车字符。
【例2-8】编写程序,使用getchar输入两个字符,然后再输出它们。(源代码\ch02\2-8)
运行上述程序,结果如图2-8所示。
图2-8 连续输入
【代码解析】
在本例中,如果需要连续输入两个或者更多字符时,需要在输入下一个字符前加上“getchar()”语句。“getchar()”语句是获取回车符,因为一般在输入字符后会按回车键确认,此时回车符就会被输入,而使用“getchar()”语句相当于将输入的回车符存入缓冲区,这样使得下一句的输入函数能够正常获取下一个字符。
putchar()函数是字符输出函数,作用是向标准输出设备(显示器)上输出一个字符,同一时间内只能输出一个单一的字符。
其语法格式如下:
putchar(ch);
提示
其中的ch可以是常量、变量、转义字符或表达式等,其数据类型可以是字符型或整型,如果是整型数据,代表的是与一个字符相对应的ASCII码值。
例如:
putchar('A'); // 输出大写字母A putchar('a'); // 输出小写字母a putchar(a); // 输出字符变量a的值 putchar('101'); // 转义字符,输出字符A putchar('\n'); // 转义字符,换行
注意:
(1)putchar函数只能用于单个字符的输出,且一次只能输出一个字符。
(2)在程序中使用putchar函数,务必牢记:在程序(或文件)的开头加上编译预处理命令(也称包含命令),即:#include <stdio.h>。
例如:
【例2-9】编写程序,要求使用putchar()函数输出字符串“New year”。(源代码\ch02\2-9)
运行上述程序,结果如图2-9所示。
图2-9 putchar()函数
【代码解析】
本例用于演示通过使用putchar()函数,将定义的字符变量输出,组成字符串。程序中首先定义字符变量ch1、ch2、ch3。然后分别为它们赋值,再通过使用putchar()函数将字符串补齐后将它们一一输出,使用putchar()函数输出字符时,如果没有特意输出换行转义符的话,每个字符是连续输出的。
gets()函数是字符串输入函数,其作用是从输入流的缓冲区中读取字符到指定的数组,直到遇见换行符或者读到文件尾时停止。
注意:
(1)gets()函数可以直接输入字符串,并且只能输入字符串。scanf()函数是通过格式控制符“%s”输入字符串。
(2)gets()函数在读取字符串时会忽略掉所有前导空白符,而从字符串第一个非空白符读起。并且所读取的字符串将暂时存放于给定的string中。
gets()函数的使用语法如下:
char *gets(char *string);
其中string为字符指针变量,是一个形式参数。gets()函数的返回值为char型,若读取成功返回string的指针,若失败则返回NULL。
【例2-10】编写程序,定义xchar型数组str1[]和str2[]用于存放输入的字符串,使用gets()函数读入一个字符串,然后使用printf()函数将该字符串输出。(源代码\ch02\2-10)
运行上述程序,结果如图2-10所示。
图2-10 get()函数
【代码解析】
本例演示了如何使用gets()函数从输入端读取一个字符串。代码中首先定义两个char型数组str1[]和str2[],注意这两个数组的长度为30,作为了解,数组所定义的长度意为该数组所能存储的数据上限。最后使用printf()函数将输入的字符串输出。
puts()是字符串输出函数,该函数是向输出缓冲区中写入一个字符串,在字符串输出完毕后,紧跟着输出一个换行符“\n”。
提示
puts()函数可以直接输出字符串,并且只能输出字符串。printf()函数通过格式控制符“%s”输出字符串。
puts()函数的使用语法如下:
int puts(char *string);
其中string为将要输出的字符串。输出成功后返回值为非0值,否则返回0。
【例2-11】编写程序,定义一个char型数组str[],并初始化为“My first C program”,使用puts()函数将字符串输出。(源代码\ch02\2-11)
#include <stdio.h> int main() { char str[] = "My first C program"; // 定一个字符串数组 printf("%s\n", str); // 通过变量输出 printf("%s\n", "My first C program"); // 直接输出 puts(str); // 通过变量输出 puts("My first C program"); // 直接输出 return 0; }
运行上述程序,结果如图2-11所示。
图2-11 puts()函数
【代码解析】
本例用于演示一个字符串的4种输出方式。代码中首先定义了一个char型数组str[],然后初始化str[]数组为“My first C program”。先使用printf()函数通过变量和直接输出的方式打印出数组str,再使用puts()函数通过变量和直接输出的方式打印出该数组。
通过对比发现,puts()函数与printf()函数的用法一样。但是puts()函数在输出字符串后会自动输出一个回车符“\n”,而printf()函数需要使用回车符“\n”才能实现换行。
提示
在printf()函数中使用%s输出字符串时,在变量列表中给出数组名即可,不能写为printf("%s",str[]);
关键字是C程序中的保留字,通常已有各自的用途。在C语言的程序编写中不允许标识符与关键字相同。与其他计算机语言相比,C语言的关键字较少,ANSI C标准一共规定了32个关键字,如表2-3。
表2-3 关键字
在程序中使用的变量名、函数名、标号等统称为标识符。除库函数的函数名由系统定义外,其余都由用户自定义。
命名必须遵循以下基本规则:
(1)标识符只能是由英文字母“A~Z,a~z”、数字“0~9”和下划线“_”组成的字符串,并且其第一个字符必须是字母或下划线。如:
int MAX_LENGTH; // 由字母和下划线组成
(2)标识符不能是C语言的关键字(见表2-3)。
(3)C语言对大小写是敏感的,程序中不要出现仅靠大小写区分的标识符,如:
int x,X; // 变量x与X容易混淆
(4)标识符应当直观且可以拼读,让别人看了就能了解其用途。标识符最好采用英文单词或其组合,不要太复杂,且用词要准确,便于记忆和阅读。切忌使用汉语拼音来命名。
(5)标识符的长度应当符合最短的长度表达最多的信息原则。
例如,以下为合法标识符:
UserName Int2 _File_Open Sex a_3 _a3
注意:
(1)在标识符中,大小写是有区别的。例如BOOK和book是两个不同的标识符。
(2)标识符虽然可由程序员随意定义,但标识符是用于标识某个量的符号。因此,命名应尽量有相应的意义,以便阅读理解,做到“顾名思义”。
本节通过具体的综合案例对本章知识点进行具体应用演示。
【例2-12】编写程序,通过输入整型变量a和b,并使用本章学习的printf()函数以及格式控制符对数据进行输出。(源代码\ch02\2-12)
运行上述程序,结果如图2-12所示。
图2-12 宽度标志和精度标志的演示
【代码解析】
本例用于演示格式控制符对宽度和精度的操作。首先定义两个整型变量并赋初始值a=-456,b=456。通过格式控制符对一正一负的整数输出后,发现不仅是宽度和精度发生了变化,数字所在的位置也发生变化,正数是右对齐,负数是左对齐。当打印整数时,如果整数的位数比精度的位数少,就在左边的空位上补0;否则按实际位数打印。
通过本章内容的学习,加深对综合案例的理解,并进行具体应用演示。
【例2-13】编写程序,通过输入端分别输入int、float、double、char型数据,使用各类格式控制符对数据进行输出。(源代码\ch02\2-13)
运行上述程序,结果如图2-13所示。
图2-13 各类控制符的演示
【代码解析】
本例演示了输入输出函数和各类控制符的使用。在代码中,定义一个char型数组,然后分别定义int、float以及double型变量。首先使用puts()函数打印出一串字符,然后用gets()函数获取这串字符并存于s数组中,再通过printf()函数与puts()函数输出这串字符,最后通过printf()函数以及格式控制符输出不同格式的数据。使用strcpy()函数也能将字符串存入数组中并通过格式控制符打印出来。
疑问1:如果在输入输出格式说明符中再插入转义字符会有什么不同?
答:通过对输入及输出的比较,可以发现以下结论:
(1)在输入说明符中插入转义字符时,相当于插入分隔符,所以在输入数据时,必须以相应的转义字符作为分隔符。
例如:
scanf("%d\n%c\t%c",&a,&b,&c);
在输入abc时,先输入a,然后输入回车换行,输入b,再输入分隔符Tab,最后输入c。
(2)在输出说明符中插入转义字符时,直接输出转义字符所对应的含义。
疑问2:C语言中,输入一个字符串使用scanf(“%s”)和gets()有什么区别?
答:使用scanf()函数时不能够接收空格、制表符Tab以及回车等,在输入的时候遇见空格、回车等会认为输入结束,而gets()函数却能够接收空格、制表符Tab以及回车。
疑问3:getch()和putch()有什么共同点?
答:都不需要加入格式控制符,并且这两个函数都可以让用户按下任意键而不需要回车就可以接受用户的输入。
疑问4:复合语句为什么不能加“;”?
答:编译器规定C语言中的复合语句使用一对大括号“{}”界定的语句块,如果加上分号,编译器就会报错。
疑问5:使用scanf()函数进行输入时,需要注意哪些问题?
答:使用时应注意的问题:
(1)要求在程序运行中输入数据,输入的数据个数和类型必须与格式说明符一一对应。
(2)地址参数形式:&变量名(除数组或指针变量)。
(3)格式控制中有普通字符时,必须照原样输入。
(4)格式控制中无普通字符时,输入的数值型数据和字符串用空白符分隔,字符型数据不必分隔。
(5)double型数据输入时,必须用%lf或%le格式。
(6)实型数输入时域宽不能用m、n形式的附加说明。
(7)为了减少不必要的输入量,除了逗号、分号、空格符以外,格式控制中尽量不要出现普通字符,也不要使用'\n'、'\t'等转义字符。
练习1:从键盘上输入一个大写字母,编写程序输出该字母的小写形式。
练习2:从键盘上输入一个英文小写字母,编程输出该字母所对应的ASCLL码。
练习3:以下函数实现数据的输入输出和运算,请更正程序中的二个错误:
int main() { float x,y,z; scanf("%5.2f%5.2f",&x,&y); z=x+y; printf('%F+%F=%F\n',x,y,z); return 0; }
练习4:分析下面程序的运行结果:
#include<stdio.h> int main() { int x=1,y=5; printf("x=%%d, y=%d\n",x,y); return 0; }
练习5:编写程序,使用printf()输出函数,输出“Hello C program!”的左侧8个字符,并将结果以左对齐的形式展现。