写在话前
几年前就在大学课堂上学过C语言,但是学得不深,平时用的不多,顶多就是课程设计的时候用用,最近打算看看书进阶一下
第一章 初始C语言
- 编程机制:
-
C语言编程的基本策略是,用程序把源代码文件转换成可执行文件
-
通过编译和链接两个步骤完成
-
编译器把源代码转换成中间代码
-
链接器把中间代码和其他代码合并
-
生成可执行文件
-
中间代码有多种形式,最普遍的是把源代码转换为机器语言代码,并把结果放在目标代码文件中。但目标代码文件缺失启动代码和库函数。前者充当程序和操作系统之间的接口,后者是因为C程序都要使用C标准库中的函数
-
第二章 C语言概述
- 注释:/**/注释中间,可单独一行也可多行;//注释之后的内容,只能注释一行
- 代码中的圆括号()表示这是一个函数,如main()和printf()
- C语言没有赋值语句,是通过赋值运算符完成赋值操作,所谓C语言的“赋值语句”其实是表达式语句
- 有返回值的C语言函数要有return语句。若遗漏,程序在运行至最外面的右花括号]时会返回0,但是不建议直接省略
- 提高程序可读性:
- 选择有意义的函数名
- 写注释
- 用空行分隔不同部分
- 每条语句各占一行
第三章 数据和C
-
字符和字符串
char apple;//变量声明 apple = 'a';//单引号——字符 apple = "a";//双引号——字符串
-
C语言将字符常量视为int,而不是char
char grade = 'B'; char fate; fate = grade; printf(fate);//显示 E
本来‘B’对应数值66,储存在32位的存储单元中,现在却可以储存在8位的存储单元中。
但是把字符常量grade赋值字符变量fate,只有最后8位有效,所以fate = ‘E’
-
单引号只适用于字符、数字和标点符号,所以要用到转义序列
-
无论是普通字符还是转义字符,只要是双引号括起来的字符集合,就无需用单引号括起来
-
初始化变量/常量的时候要注意所占内存范围是否满足
第四章 字符串和格式化输入输出
-
字符串是一个或多个字符的序列
-
C语言没有专门用于储存字符串的变量类型,字符串都被储存在char的数组中。
char name[40];//字符串初始化
数组由连续的存储单元组成,字符串中的字符被储存在相邻的存储单元中,每个单元储存一个字符。
其中数组末尾位置的字符\0,是空字符(ASCII码值为0),用来标记字符串的结束,计算机会自行放入。C语言中的字符串一定以空字符结束。
所以数组的容量必须至少比待存储的字符串中的字符多1。
-
注意:
输入angela plains时,只会输出angela,遇到第一个空格就停止了,所以scanf()只会读取字符串中的第一个单词,而不是一整句
char name[40]; scanf("%s, name); printf("%s", name);
-
“x”和’x’不同,后者是基本类型char,前者是派生类型char数组,实际上由两个字符组成(’x’和空字符\0)
-
srelen()和sizeof():
char name[40]; scanf("%s", name);//输入tuffy printf(strlen(name));//输出5,第6个单元储存空字符,并未计入 printf(sizeof(name));//输出40
同时需要注意的是,对于特定量,可以写成sizeof name或者sizeof 6.28,对于类型,要写成sizeof(int),但是建议全都写成sizeof()
-
printf():
-
printf()的转换和修饰符
-
要注意转换匹配,转换不匹配时(h:short int;%u:unsigned int)
/*声明时默认为有符号*/ short num = 336; short mnum = -336;//对应二进制补码为65200 /*第1行,输出无任何问题*/ printf("%hd %hu", num, num);//输出336 336 /*第2行,第2个输出为65200,因为有符号short int类型的值大小为2字节, 而且系统使用二进制补码表示有符号整数: 0~32767代表本身,32768~65535表示负数, 其中,65535为-1,65534为-2,以此类推,65200为-336 所以,被解释为有符号int时,65200为-336,被解释为无符号int时,65200为65200*/ printf("%hd %hu", mnum, mnum);//输出-336 65200 /*第3行,演示了把一个>255的值转换成字符会发生什么 short int为2字节,char为1字节 当printf()使用%c打印>255的值,系统只会查看储存336的2字节后的1字节 相当于用一个整数除以245,取其余数,即以256为模 在该情况下,余数为80,对应ASCII值为P */ printf("%d %c", num, num);//输出336 P /*第4行,short int最大整数为32767,而65618>32767 此处也进行了求模 在本系统中,应把数字65618储存为4字节的int 用%hd时,printf()只使用最后2字节,即65618除以65536取余数82 如果余数在32768~65535,会被打印为负数 */ printf("%d %hd %c", 65618, 65618, 65618);//输出65618 82 R
-
c. printf()的返回值:返回打印字符的个数,包括空格和不可见的转义字符。如\n(算一个)
-
如果打印长内容,换行方法:
printf("here is the "); printf("first way.\n"); printf("here is the \ second way.\n"); printf("here is the " "third way.\n"); //不能在双引号中间进行换行 printf("here is the wrong way.\n");
-
-
scanf()
-
如果读取基本变量类型,在变量名前加&
-
如果把字符串读入字符数组中,不要使用&
-
转换说明和修饰符
-
从scanf()看输入:
scanf("%d", &n);//输入-13.45e2# 0 printf("%d", n);//输出-13
-
返回值:成功读取的项数。如果没有读取任何项,且需要读取一个数字而用户却输入一个非数值字符串,则返回0
-
-
*修饰符
-
printf()的*修饰符:*代替字段宽度,如%*d
unsigned width = 8, precision = 3; int number = 256; printf("%*d", width, number);//width提供字段宽度,number是待打印的数字 //由于*d中*在前面,所以width在先 printf("%*.*f", width, precision, number);//宽度,小数精度,待显示数字
-
scanf()的*修饰符:使得跳过相应输出项,如%*d
scanf("%*d %*d %d", %n);//输入2023 2024 2025 printf("%d", n);//输出2025
-