一.初识C语言
C语言的起源
1972年,贝尔实验室的丹尼斯.里奇和肯.汤普逊在开发UNIX操作系统时设计了C语言,C语言是在B语言(汤普逊发明)的基础上演变而来的。
选择C语言的理由
优点:高效性,可移植性 ,强大而灵活 ,面向程序员
缺点: 危险性高,开发周期长
应用范围
20世纪80年代被用作小型计算机(UNIX系统)使用的主流语言,是大部分流行编程语言的起源。
语言标准
1989年正式发布(ANSI C),也就是我们俗称的C89,1994年发布C99标准,2001年发布C11标准
使用C语言的7个步骤
1.定义程序的目标
明确自己想要做什么,思考程序需要用到哪些信息,需要进行哪些计算和控制,以及程序应该报告什么信息。(用一般术语描述问题)
2.设计程序
选择一个合适的方式表示信息。(即代码思路)
3.编写代码
将设计的程序翻译成C语言。
4.编译
编译器将源代码转换成可执行的程序。
5.运行程序
可执行文件是可运行的程序。
6.测试和调试程序
发现错误,即bug,查找并修复程序错误的过程称为调试。
7.维护和修改代码
创建完程序后,发现程序有错误,或者想拓展程序的用途,这是就需要修改程序。
编译机制
源代码文件:在编译器中输入的内容,并存储在文本文件中。编译器把源文件转换成中间代码,链接器把中间代码和其他代码合并,生成可执行文件。启动代码充当着程序和操作系统之间的接口。
二.C语言概述
头文件include ,main()函数,注释的用法,函数声明,赋值,函数简单结构:函数头(函数名,传入函数的信息类型,函数返回类型)函数体(声明以及一系列语句)
提高程序可读性的技巧:有意义的函数名,写注释,在函数中用空行分隔概念上的多个部分
三.数据和C
整数类型和浮点类型
int:存储整数类型数字
float:存储带小数的数字
- 计数法示例:
数字1000000000 科学计数法 1.0*10^9 指数计数法 1.0e9
数字0.000056 科学计数法 5.6*10^-5 指数计数法 5.6e-5
布尔类型
- _Bool——布尔类型的关键字,无符号int类型,可储存0或1
变量和常量
在整个程序的运行过程中没有变化,这些称为常量,可能被改变或被赋值的称为变量。
关键字
int,short,signed,unsigned,unsignde short int,long long int,char,float,double,long double
int型:储存要占1个机器字长,16位机器,范围-32768 ~ 32767目前大多数机器32位,即占4个字节,存储数字范围为:-2147483648 ~ 2147483647
short型:存储小于等于int,-32768 ~ 32767
long型:储存大于等于int,-2147483648 ~ 2147483647
long long型:存储至少64位,即8个字节
unsigned型:无符号,只能存储正整数,能存储比signed更大的整数
目前普遍设置:long long 64位8字节,long 32位4字节,short 16位2字节,int 16/32位 2/4字节
char型:一个字节,-128 ~ 127,ASCII编码0~127,存储绰绰有余,C语言将字符常量视为int型非char型,是否有符号看编译器
float:至少6位有效数字,取值至少10的-37到+37次方。通常浮点占32位,8位指数的值和符号,剩下的24位非指数的值和符号。
double:至少13位有效数字。通常64位,剩下的32位给非指数部分。
long double 更高的精确要求,至少比double精确
位、字节和字
位:最小的存储单元是,可以储存0或1
字节:常用储存单位字节,1字节均为8位
字:设计计算机时给定的自然存储单位,对于8位微型计算机,1个字长只有8位,如今,个人计算机字长已增至16位,32位,64位。
转义序列
\a警报,\b退格,\f换页,\n换行,\r回车,\t水平制表符,\v垂直制表符,\反斜杠(\),'单引号,"双引号,?问号,\0oo八进制,\xhh十六进制
可移植类型 stdint.h和inttypes.h
intmax_t 可储存任何有效的有符号整数集,uintmax_t 表示最大的无符号整数类型
复数和虚数类型
复数:float_Complex,double_Complex,long double_Complex
虚数:float_Imaginary,double_Imaginary,long double_Imaginary
类型大小
sizeof()函数
sizeof(int),sizeof(char),sizeof(long)等等
参数和陷阱
printf函数与scanf函数中
例如:printf("%d%d",a,b);%d为转换说明,说明后面有两个参数
刷新输出
printf()语句把输出发送到一个叫缓冲区的中间存储区域,然后缓冲区的内容不断被发送到屏幕上。C标准规定当缓冲区满、或遇到换行符或需要输入的时候(送缓冲区把数据发送到屏幕或文件被称为刷新缓冲区)。例如:前两个printf()语句既没有填满缓冲区,也没有换行符,但是下一条scanf()语句要求用户输入,这时printf()的输入被发送到屏幕上去
四.字符串和格式输入\输出
字符串简介
字符串是一个或多个字符的序列,如"Hello world!",双引号不是在字符串的一部分,双引号告知编译器它括起来的是字符串,正如单引号用于标识单个字符一样
char类型数组和null字符
C语言中没有专门用于储存字符串的类型,而是储存在char类型的数组中,数组末尾的\0,这是空字符(null),标记着字符串的结束,空字符不是0,它是非打印字符,其ASCII码值是0
scanf()只会读取字符串中的一个单词,因为scanf()读取到空格时就停止了
strlen()函数
- 需要string.h头文件,测量字符串的长度
- 与sizeof()区别:sizeof()会将字符串末尾不可见的空字符也计算在内
C预处理器
C预处理器为预处理器指令(以#符号开始)查找源代码程序,并在开始编译之前处理它们。
' #define pi 3.14159 ',程序中pi的值均为3.14159,这一过程被称为编译时替换
const限定符
const关键字用于限定一个变量为只读,如:
const int MONTHS = 12;
这使得 MONTHS称为一个只读值,不可以被改变
注:const类型限定符声明的是变量,不是常量
明示常量
- limits.h和float.h分别提供了整数类型和浮点类型大小限制的详细信息
如:
#define INT_MAX +32767
#define INT_MAX +32767
这些明示常量代表int类型可表示的最大值和最小值
- float.h头文件中也定义一些明示常量,如FLT_DIG和DBL_DIG,分别表示float和double类型的有效数字位数
printf函数
转换说明 | 输出 |
---|---|
%a | 浮点数、十六进制数和p计数法 |
%A | 浮点数、十六进制数和p计数法 |
%c | 单个字符 |
%d | 有符号十进制整数 |
%e | 点数,e计数法 |
%E | 浮点数,e计数法 |
%f | 浮点数,十进制计数法 |
%g | 根据值的不同,自动选择%f或%e。%e格式用于指数小于-4或等于精度时 |
%G | 根据值的不同,自动选择%f或%E。%E格式用于指数小于-4或等于精度时 |
%i | 有符号十进制整数(与%d相同) |
%o | 无符号八进制整数 |
%p | 指针 |
%s | 字符串 |
%u | 无符号十进制整数 |
%x | 无符号十六进制整数,使用十六进制数of |
%X | 无符号十六进制整数,使用十六进制数OF |
%% | 打印一个百分号 |
printf函数转换说明修饰符
修饰符 | 含义 |
---|---|
数字 | 最小字段宽度 |
.数字 | 精度 |
scanf()函数
- 将输入的字符串转换成整数,浮点型,字符或字符串,与printf()函数的功能刚好相反,转换说明与printf()函数的相似
- printf()函数使用变量,常量,和表达式,而scanf()函数使用指向变量的指针
scanf()的返回值
当scanf()检测到"文件结尾"时,会返回EOF(EOF是stdio.h中定义的特殊值,通常用#define指令吧EOF定义为-1)
printf()和scanf()的*修饰符
printf("%*d",width,number);//width表示字段宽度,number表示变量
-
scanf()函数中将*放在%和转换字符之间时,会使scanf()跳过相应的输出项。
scanf("%d,%d,%*d",&n);//跳过两个整数,把第3个整数拷贝给n
五.运算符、表达式和语句
运算符
一般而言,运算符需要一个或多个运算对象才能完成运算生成一个值。只需要一个运算对象的运算符(如符号和sizeof)被称为一元运算符,需要两个运算对象的运算符(如加法运算符和乘法运算符)称为二元运算符。
赋值运算符
- 在C语言中,=并不意味着“相等”,而是一个赋值运算符
- =号左侧的项必须是一个变量名,赋值运算符左侧必须引用一个存储位置,最简单的方法就是使用变量名
- 赋值运算符的目的是把值储存到内存位置上,用于储存数据存储区域统称为数据对象
- 可修改的左值用于标识可修改的对象,术语为对象定位符
- 右值是指能赋值给可修改左值的量
除法运算
- 整数除法的结果是整数,浮点数除法是浮点数。在C语言中整数除法结果的小数部分被丢弃,这一过程被称为截断
- 混合整数和浮点数计算的结果是浮点数。事实上,计算机不能真正用浮点数出于整数,编译器会把两个运算对象转换成相同的类型
运算符优先级
对大多数运算符而言,是按从左到右的顺序进行的(=运算符除外)
求模运算符
负数求模:如果第一个运算对象是负数,求模结果就是负数,如果第一个运算对象是正数,求模结果就是正数
表达式
- 表达式有运算符和运算对象组成,最简单的表达式是一个单独的运算对象
- 每个表达式都有一个值
语句
- 语句是C语言的基本构建快,一条语句相当于一条完整的计算机指令,分为简单语句和复合语句。
- 简单语句以一个分号结尾
- 复合语句是用花括号括起来的一条或多条语句,复合语句也被称为块
- 最简单的是语句是空语句。
副作用
副作用:对数据对象或文件的修改
states = 50;
它的副作用是把变量的值设置为50,虽然这看起来是主要目的,但从C语言的角度来看,主要目的是对表达式求值
类似地,调用printf()函数的时候,它显示的内容是副作用(printf()的返回值是待显示字符的个数)
序列点
序列点是程序执行的点,在该点上,所有的副作用都在进入下一步之前发生,在C语言中,语句的分号就标记了一个序列点,意思是,赋值运算符、递增运算符和递减运算符对运算对象的改变必须在程序执行下一条语句之前完成。
- 完整表达式:就是指这个表达式不是另外一个更大的表达式的子表达式。
while()函数的缩进问题
int i=1;
while(i++<3)
printf("aaa\n");
printf("bbb\n");
int i=1;
while(i++<3)
printf("aaa\n");
printf("bbb\n");
这两段代码的运行结果都是相同的,缩进对编译器不起作用,缩进只是让读者一眼能够看出程序是如何组织的。如果没有花括号,while语句从while这行运行向下到第一个分号。
强制转换
强制类型转换运算将其右侧的值转换成圆括号中指定的类型,如(float)9把整数9强制转换成浮点数9.0
带参数的函数
- 函数头中包含参数,声明参数就创建了被称为形式参数的变量,并且我们将函数调用传递的值称为实际参数
- 变量名是函数私有的,即在函数中定义的函数名不会和别处的相同名称发生冲突。