第1章
1.1 创建一个C程序
这里使用的不是学校上课用的编程软件,而是Dev C++ 5.4.0。安装的时候可以选择中文。
新建一个新文件即可。后缀名默认是.cpp,不过c++的编译器是能识别c语言书写的绝大多数代码的(如果有特例会说明)。
1.2 C程序的基本组成
int main() //函数头
{ /*函数体开始*/
return 0; //语句,推出主函数,结束程序的运行并返回0
} /*函数体结束*/
与pascal或者Python不同,C语言中不存在“函数”之外的代码。在上面的代码中,我们定义了一个名字为main,返回值为整形(int)的函数。
C语言有三个基本概念:函数、语句、注释。上面的代码只有一个名为main的函数,一个语句以及几句注释。
函数包括函数头和函数体。int main()是函数头,main是函数名,括号()中是函数的参数表。main前面的int就是函数返回值的类型。这三样也被称为函数原型。至于为什么需要返回一个值,之后的例子会有体现。函数体由被{}括起来的一系列语句组成。说明函数要进行的操作和运算。语句是C语言的基本执行单位,一般以‘;’分号结束。一个程序可能有很多函数,但main函数有最高的优先级,是整个程序的入口和出口。通常return 0表示程序正常结束,非0则表示非正常结束(但在某些操作系统或编译器中,main函数可以没有返回值,写成void main())。在通常情况下,一个main函数至少应包含一个return 0语句。
注释也是重要的组成部分。//是单行注释的标志,注释符号开始到这一行结束的所有字符全部是注释的一部分。也可以用/* */创建一个多行注释。被注释的内容改变颜色和字体,很容易看出。
除了自定义函数之外,语句中会包含一些语言设计者“规定”的函数,比如printf(),这时候我们就需要调用安装编译器时已经安装好的库:
#include<stdio.h>
int main() { printf(“Hello,world!\n”) return 0; }
上面的样例有一个小问题,那就是printf()语句后面没有加“;”,结果就是编译器会报错。错误信息通常会包含错误位置,类型和原因。看懂错误信息对于改正程序的错误,也就是debug很重要。“\n”是一个换行符,但在这个程序的输出中是看不出来的。知道常见函数所属于的库函数是很有用的。
常用的函数:
scanf():从键盘上按照规定格式读入数据。
常用字段类型说明符:
%d/%x int 有符号的十进制/十六进制
%f/%lf float/double 实数/实数
%c/%s char/char 字符/字符串
putchar():向终端屏幕输出一个字符。
fgets():从键盘上读入一行字符。
time():获得当前时间。
rand():生成一个随机数。
第2章
2.1 常量
如果我们需要多次用到一个极大的数字或者一个极长的字符串,我们不妨在程序的开头定义一个名字较短的常量,这样就可以节省我们的时间。
首先是整数。除了十进制之外,C语言中的整数也可以用十六进制或八进制表示。十六进制由前缀0x引导,数字0~9和字母a~f(大小写均可)组成。a~f对应十进制的10到15。八进制整数以0开头。定义常量的语句如下:
#include<stdio.h>
#define A 90
int main() { printf("%d",A); return 0; }
缩进、换行和参数的命名全看个人习惯。不如把90换成0x5a试试看?换成0132呢?
然后是实数。在C语言中有两种表现方式:算术法和科学表示法。科学表示法的指数部分是e或E开头的整数。比如0.12E3表示120。
字符和字符串常量类似。只要记得把字符和字符串放在一对引号中即可。单引号代表字符,双引号代表字符串。
2.2 变量
总体上来说,变量分为局部变量和全局变量。全局变量定义在函数之外,所有函数中都可以使用。局部变量则定义在函数内,只有在被定义的那个函数中才有意义。C语言中,变量在使用前必须定义(某些语言中可以先用再定义,这和编译器的运行方式有关)。
单从有无小数部分来看,数值变量可以分为只能表示整数的定点型和和可以表示实数的浮点型两大类。
定点型又可称为整型,分为char,short,int,long四个小类。每个小类又可以根据是否能表示负数而分为有符号数和无符号数。
部分整型数据的数值表示范围如下:
char -128~127 unsigned char 0~255
int -2147483648~2147483648
unsigned int 0~4294967295
long与int范围相同,unsigned long与unsigned int范围相同。如果需要大一些的数字,可以用long long类型。需要存储更大的数字的话,就需要数组了。
浮点型数据分为float和double两个小类。float类型是单精度类型,表示范围约为-3.4*10^38~3.4*10^38。能表示的绝对值最小的数值为10^(-44.85)。而有效数字大约相当于十进制的7位。double类型是双精度类型,有效数字相当于十进制的15位。
赋值操作的表达式为
<变量名>=<表达式>;
变量名即之前声明过的名称,表达式是某个算术式。“;”不要漏掉。需要注意的是“=”两边应当是类型相同的数据类型。当然,如果实在不一样,我们可以在表达式前面写上(类型)来将等号右边的数据类型变的与左边相同。不过,数据的“宽度(即所占用字节数)”不同。显然将宽度大的数据结构转换为宽度小的类型的时候数据会有损坏或者丢失,而宽度小的类型转换为宽度大的类型则没有任何问题。
闲谈一句,在变量的使用中还有const这个奇怪的东西,这个单词的作用是把变量编程一个“常量”,也就是你不能改变它的值:
const n=5;
2.3 算术表达式
加 + 减 - 乘 * 除 / 取余(模) %
注意:5/2=2(相当于取整) 5.0/2.0=2.5 5.0/2=2.5
*/%的优先级高于+和-
运算中通常会遇到对变量的值加1或减1的情况。++是对变量值加1的运算符,--是减一。++和--的位置对于表达式的值有影响。
int j=1;
v=++j; //v==2
v=j++; //v==1
算术中还有一个有趣的操作叫位运算。x<<y的结果等于x的值在二进制的情况下左移y位,不难理解这相当于将x*2^y。同理,x>>y的结果等于x/2^y。
按位运算包括“与”(相同为真)“或”(有真则真)“异或”(不同则真)。
2.4 强制类型转换
(类型名) 表达式
把double类型转换为int型相当于取整,稍微再操作一下就可以得到小数部分。
有趣的是:
int x;
float f=0.04;
x=(int) (f*100);
结果会是3,而不是4。这是因为C语言在强制转换的时候,是按照该浮点数在计算机内部的实际值操作的。存储的时候f会略小于0.4……而如果用double类型,结果就会是4了。
2.5 数据输入/输出函数
常用输出函数为printf()。举个例子。
printf(“Hello world!”); 结果为:Hello world!
int a=1,b=2; printf(“%d%d”,a,b); 结果为:12
int a=1,b=2; printf(“%d %d”,a,b); 结果为:1 2
int--%d int--%x(十六进制)double--%e(实数的科学表示法)%f(实数的常规表示法)
char--%c char*--%s(字符串)
除了数字和字符之外,printf()括号中包含的内容还可以有转义符。同时可以限制字段宽度、保留小数点的位数(%.2f就是保留两位小数的意思)等等。
常用输入函数为scanf()。括号中的内容为变量类型和变量所在的地址。
scanf(“%d”,&a);
上面的语句可以实现读入a的值。如果scanf语句要读入多个变量,他会忽视输入中的空格和回车。还有一些有趣的匹配方式,或许会在之后的总结中出现。
2.6 枚举常量
定义枚举常量需要用关键字enum引导的枚举符表。举个例子:
enum{A,B,C,D,E=50,F,G,H,I,J,K};
上面的语句中包含11个枚举符,定义了从A到K共11个枚举常量。当枚举常量形式和E一样的时候,这个枚举符的值就是等号后的表达式的值。否则就是前面枚举常量的值+1。像A这样的第一个枚举常量,它的值默认是0。所以上述枚举常量的值分别为0,1,2,3,50,51,52,53,54,55,56。