一.字符串
1.char数组类型和空字符
c没有为字符串定义专门的变量类型,而是把它存储在char数组中。
将数组看成是一行中的多个存储单元,字符串中的每个字符占用一个字符,最后一个位置显示空字符\0,标记字符串的结束。因此意味着数组的单元数必须至少比要存储的字符数多1。(与字符的主要区别:"x"是由两个字符组成('x'和'\0'))
2.打印字符串
#include<stdio.h>int main(void){char name[40];scanf("%s",name);printf("%s\n",name);return 0;}
%s表示打印字符串的说明符。
输入yang yang时,为什么只输出了yang而不是整个字符串呢?因为scanf()开始读取后,遇到的第一个空白字符空格、制表符或者换行符处停止读取。所以,使用%s的scanf()只会读取一个单词而不是把整个语句作为字符串读入。c使用其他读取输入函数(例如gets()来处理一般的字符串)。
3.strlen函数
上一节的sizeof运算符,以字节为单位给出数据的大小。strlen()函数以字符为单位给出字符串的长度。
#include<stdio.h>#include<string.h>#define PRAISE "what a super marvelous name!" int main(void){char name[40];scanf("%s",name);printf("%d %d\n",strlen(name),sizeof name);printf("%d %d\n",strlen(PRAISE),sizeof PRAISE);return 0;}
输入yang yang,结果为:
4 40
28 29
string.h文件包含许多与字符串相关的函数的原型,例如strlen()。c把c函数库分成多个相关函数的系列,并为每个系列提供一个头文件。
由结果可知,strlen()报告了字符串的长度,即4和28,其中包含空格。而sizeof在数组中报告数组的大小,与字符串的长度无关。而在常量中为29,比前者多1,原因是将字符串的不可见的空字符\0也计算在内。
sizeof对于类型来说括号是必需的,对于具体量来说是可选的。不过加上会更好。
二.定义常量
c预处理器
#define NAME value
键入大写的常量名是一个很好的习惯。它在程序头位置定义。无类型,无赋值运算符。
const修饰符
const type name=value
它在函数中定义。相当于常量声明,需要声明类型,具有赋值运算符。
枚举(enum)功能
(以后再讲)
三.I/O函数
1.printf()函数
前面讲过转化说明符和参数列表,这次主要讲输出格式控制和返回值。
整数的字段宽度修饰符:
#include<stdio.h> #define PAGES 931int main(void){printf("*%d*\n",PAGES); //生成一个与要打印的整数宽度相同的字段printf("*%2d*\n",PAGES); //指示产生宽度为2的字段,但由于该整数有三位数字,故字段自动扩展以适应数字的长度printf("*%10d*\n",PAGES); //产生宽度为10即10个空格那么宽的字段,又为正数,则位于整个字段的右端printf("*%-10d*\n",PAGES); //宽度为10,且为负数,位于整个字段的左端return 0;}
输出结果:
浮点数的格式修饰符:
#include<stdio.h> int main(void){const double RENT=3852.99;//以const方法定义的常量printf("*%f*\n",RENT); //原数字输出,但是根据类型的有效数字为至少六位printf("*%e*\n",RENT);printf("*%4.2f*\n",RENT);//小数点左边的数为字段宽度,右边的数为输出数字的有效数字printf("*%3.1f*\n",RENT);printf("*%10.3f*\n",RENT);printf("*%10.3e*\n",RENT);//字段宽度作用于整个数字,包括小数点;有效位数作用于指数部分printf("*%+4.2f*\n",RENT);//+标志使得数字与它的代数符号一起打印printf("*%010.2f*\n",RENT); //0标志产生前导零使得使得结果填充整个字段return 0;}
输出结果为:
其他格式:
#include<stdio.h> int main(void){printf("**%d**% d**% d**\n",42,42,-42);//在说明符中使用空格以在正值之前产生一个前导空格,将使有效位相同的正值和负值以相同字段宽度输出printf("**%5d**%5.3d**%05d**%05.3d**\n",6,6,6,6);//在整数格式中,0标志使用前导零填满整个字段,而使用小数点位则要求有多少个前导零。若同时出现,则0标志被忽略return 0;}
输出结果为:
字符串:
#include<stdio.h>#define BLURB "Authentic imitation!" int main(void){printf("/%2s/\n",BLURB);//扩展宽度printf("/%24s/\n",BLURB);printf("/%24.5s/\n",BLURB); //小数点位数表示只打印5个字符(从前往后)printf("/%-24.5s/\n",BLURB); //-表示左对齐输出return 0;}
输出结果为:
返回值
c函数一般都有一个返回值,由函数计算并返回给调用函数的值,可以用来赋值,计算和作为参数传递。总之,可以像任何值那样使用。
printf()函数返回打印的字符的数目。(一般在向文件输出而非向屏幕输出时很常用)
#include<stdio.h>int main(void){int bph2o=211;int rv;rv=printf("%d F is water's boiling point.\n",bph2o);printf("The printf() fuction printfed %d characters.\n",rv); //针对所有的打印字符,包括空格和不可见的空字符return 0;}
输出结果:
打印较长字符串
方法一:使用多个printf()语句,不用\n字符结束则会紧接下一条语句;
方法二:用反斜线/和回车键组合结束第一行:
printf("No \problem!\n"); //下一行必须从最左边开始,不能有空格或缩进
方法三:在一个双引号引起来的字符串后面跟有另外的双引号引起来的字符串,中间仅用空白字符分隔。
printf("Do you undestand" " me.\n");
2.scanf()函数
输入:
根据不同的说明符输入相应格式的数据,读取一个字符后保存在读取下一个字符,直到遇到空白字符(空格、制表符、换行符)或与说明符不同的数据。
c还有其他的输入函数,例如gets()(读取包含空格的字符串)、getchar()(专门的一个读取字符)
使用scanf()函数是因为它能够读取所有不同的数据类型,用途广泛。
返回值
scanf()函数返回成功读入的项目的个数,若没有读取任何项目(当它期望一个数字而您键入一个非数字时就会发生这种情况),scanf()返回0.当它检测到“文件结尾”时,返回EOF(一般#define指令把EOF值定义为-1)。
在循环语句中,可以使用scanf()返回值来检测和处理不匹配的输入。
3.*修饰符
printf()函数
不想事先指定而是让程序指定字段宽度,则使用*来代替数字,同时你需要使用一个参数来表示它的值。例如:%*d:参数列表中包括一个*值和一个d的值。
#include<stdio.h>int main(void){unsigned width,precision;int number=256;double weight=242.5;printf("What field width?\n");scanf("%d",&width);printf("The number is:%*d:\n",width,number);printf("Now enter a width and a precision:\n");scanf("%d %d",&width,&precision);printf("Weight = %*.*f\n",width,precision,weight);return 0;}
输出结果:
scanf()函数
把它放在%和说明符字母之间,使得函数跳过相应的输入项目。
int n;printf("Please enter three integers:\n");scanf("%*d %*d %d",&n);printf("The last integer was %d\n",n);
输出结果:
若程序需要读取一个文件中某个特定的列(该文件的数以统一的列排列),那么该功能将非常有用。