C语言学习笔记
借助C Primer Plus第六版中文版
[TOC]
一、初识C语言
基本概览,没啥好记的
二、 C语言概述
简单的C程序示例
注释略显杂乱
1 | // 这是单行注释 |
简单程序的结构
包含函数头和函数体,函数体又主要有声明和语句
建议在一开始就进行声明,虽然新规则没有要求了但最好还是这样
大部分语句都以分号结尾!!!不要忘记!!!
提高程序可读性
- 积极写注释
- 使用有意义的变量名
- 使用空行分隔
- 每行一条语句
- 程序第一行就写注释,包括程序名称和目的
进一步使用C
同时声明多个变量:使用逗号隔开
1 | int a, b; |
打印多个值:同样用逗号隔开
1 | printf("I like %d and %d !\n", food, drink); |
待打印的值不一定是变量
1 | printf("The answer is %d !", 3 * total); |
多个函数
可以将自己的函数加入到程序中。示例代码如下:
1 |
|
调试程序
语法错误:把有效的C符号放在了错误的地方
如:用圆括号代替了花括号;声明变量的写法错误;多行注释没写末尾*/;没打分号等等
语义错误:语法正确,意思上的错误
编译器无法检测,因为语言规则正确,但是运行结果不符合预期要求
如何监视程序状态?
- 对于简单代码,假设自己是计算机,模拟运行一遍
- 在程序关键点插入额外的printf,了解程序执行情况
- 利用调试器(推荐)
关键字和保留标识符
一些关键字比较特殊,不能用它们作为标识符,如int、while、break等等
还有一些是保留标识符,C语言已经制定了他们的用途或者保留了他们的使用权,比如那些以下划线字符开头的标识符和标准库函数名,比如printf
练习
进行了第5题和第8题的练习
copilot真的太好用了你知道吗?不过为了练习需求还是不开了
三、数据和C
示例代码
1 |
|
变量与常量数据
程序运行过程中没有变化的量叫做常量,在程序运行期间可能会被改变或者被赋值的叫做变量
数据:数据类型和关键字
对变量而言,要在声明时指定其类型
- int表示基本的整数类型,其关键字long、short、unsigned用于提供其变式
- char表示字母和其他字符,也可以表示较小的整数
- float、double和long double表示带小数点的数
- _Bool表示布尔值(true和false)
- _complex表示复数
- _Imaginary表示虚数
按照计算机的存储方式可以分为两大基本类型:整数类型和浮点数类型
位、字节和字
- 位bit:最小存储单元,可以储存0或1
- 字节byte:1字节有8位,有256种组合
- 字word:设计计算机时给定的自然存储单位,目前一般为64位。字长越大,数据转移越快,允许的内存访问也就更多
整数
8位字节中储存,二进制。例如7表示为0000111
浮点数
第一位表示正负号,最后一位表示10的几次幂
C语言基本数据类型
int类型
目前计算机一般是64位,所以用64位储存一个int值
声明int变量:用多行或者逗号创建变量。此步是为变量创建存储空间
初始化变量:也就是为变量赋一个初始值。方法如下:
直接赋值
1
cows = 100;
通过函数比如scanf
声明时就初始化
1
2
3int cats = 100, dogs = 200;
//不要像下面这样,把未初始化和初始化的放在同一行,容易误解
int dogs, cats = 100;
int类型常量:C把不含小数点和指数的数作为整数,它们都是整形常量。非常大的整数除外
打印int值:使用printf打印,%d(转换说明)表明了打印整数的位置(%d与所有int类型相匹配)。要确保转换说明的数量与待打印值的数量相同
八进制和十六进制:0前缀表示八进制,0x或者0X表示16进制。如16是020,也是0x10
显示八进制和十六进制:将%d换为%o或者%x、%X,就可以以8进制或者16进制显示数字。如果要在前面加上0和0x前缀,改为%#o或者%#x、%#X
其他整数类型(前缀)
- short,占空间比int少,用于较小数值场合
- long,占用存储空间比int多,较大数值场合
- unsigned,用于非负值场合
如何选择?
- 先考虑unsigned类型,此类型一般用于计数
- 超出int范围,则使用long,甚至long long
- short用于节省空间
通常,编译器会“自动”为数字选择对应的存储类型
若想在int为16为,long为32位的系统中,将“自动”存储为int类型的数值用long类型存储,则可以在该值的末尾加上l或L后缀。一般使用L因为小写l容易弄混。类似的,8进制和16进制也可以;long long则是两个L;u或U表示unsigned
1 | //例如: |
打印short、long等类型
转换说明:
unsigned int:%u
long:%ld(若系统中int和long大小相同那么%d就可以)
八进制或者十六进制就是在对应字母前加上l,如%lo、%lx
short:%hd,其他进制类似long,但是前缀是h
组合unsigned:在最后加上u后缀,如%lu、%llu
使用错误的转换说明会导致输出错误的结果
1 | //例子如下: |
整数溢出
如果整数超过了取值范围就会溢出。unsigned溢出后从0开始,int从-2147483648开始
使用字符:char类型
实际上char存储的是整数,是整数类型。所以使用ASCII编码,用特定整数代表特定字符。也有其他编码方式如Unicode
声明char类型变量
类似其他
1 | char response; |
字符常量和初始化
注意:C语言中单引号双引号不同!
1 | char broiled; |
非打印字符
如退格、换行等,可以用3种方式表示这些字符
1 | // 1.使用ASCII码,如蜂鸣字符的ASCII值是7 |
转义序列部分对照
- \a:警报
- \b:退格,移动光标位置往前一格,不是删除
输入时数据会替换掉后面的字符- \f:换页
- \n:换行
- \r:回车(回到本行第一个字符)
- \t:水平制表符
- \v:垂直制表符
- \\:取消对\的转义
- \‘:单引号’
- \“:双引号’’
- ?:问号?
- \0:后面接0-7的数字,用八进制值ASCII码表示字符
- \x:后面接0-f,用十六进制值ASCII码表示字符
一些需要注意的
- 使用ASCII码时注意数字和数字字符的区别。如字符4对应的ASCII码是52,’4’表示字符4而不是数值4
- 双引号中不需要再把转移序列用单引号括起来
- 优先使用转移序列而不是ASCII码
打印字符
在printf用%c表示待打印的字符
如果使用%d则会直接打印一个整数
有符号&无符号
有些编译器把char视为有符号类型,那么此时char表示的范围就是-128~127;有的视为无符号类型,那么范围就是0~255
可以在char前面使用signed或者unsigned
_Bool类型
用于表示布尔值true或者false,1表示true,0表示false
所以_Bool实际上也是一种整数类型
可移植类型:stdint.h和inttypes,h
头文件需要使用<inttypes.h>
此数据类型略
float、double和long double
C标准规定,float至少能表示6位有效数字,double至少可以表示10位有效数字。float一般占用32位,其中8位表示指数的的值和符号,身下24位用于表示非质指数部分;double一般占用64位而不是32位,因此至少可以表示13位有效数字
声明浮点型变量
1 | float noah, jonah; |
浮点型常量
基本形式:有符号的数字(包括小数点),后面紧跟e或E,最后是一个有符号数表示10的指数
可以省略正号;可以省略小数点(2e5)或指数部分(19.28);可以省略小数部分(3.e16)或整数部分(.45e-6)
e和E左右都不要加空格
默认情况下,编译器假定float是double类型的精度并使用双精度进行乘法运算,然后将结果截断成float,这样计算精度更高但是会损失速度。若要强制视为float类型,在数据最后加上f或F。若要强制视为long double类型,加上l或L。
C99标准添加了一种用16进制表示浮点型常量的方法,此处略
打印浮点值
在printf中使用%f表示待打印的浮点值。若要打印指数计数法的形式,用%e(C99标准也可以用%a)
打印long double,使用%Lf、%Le(或%La)
浮点值的上溢overflow和下溢underflow
上溢:当计算值过大超出当前类型能表达的范围,printf显示为inf或infinity
下溢:因为精度原因损失了有效数位,0.1234e-10除以10得到0.0123e-10
未定义浮点值
如给asin()函数输入一个大于1的值,因为sin的范围不能大于1,所以返回值是NaN,printf会显示为nan等
浮点值舍入错误
若浮点能够储存的有效数字少于运算所需的,就可能发生错误,因为计算机缺少足够的小数位来完成运算。
例如2.0e20先加1,再减2.0e20,得到的结果并不是1
复数和虚数类型
三种复数类型:float_Complex、double_Complex和long double_Complex
类似地,三种虚数类型float_Imaginary,后略
这些类型的变量包括两个float类型的值,分别用于表示复数的实部和虚部
如果包含complex.h头文件,则可使用complex、imaginary用来代替_Complex和_Imaginary
类型大小
使用sizeof()运算符,以字节为单位给出指定类型的大小,在printf中用%zd表示
1 | printf("The int has a size of %zd bytes.\n", sizeof(int)); |
使用数据类型
初始化变量时应使用与变量类型匹配的常数类型
若类型不对应,会损失部分数据,例如float转化为int会直接丢弃小数点后的值,double转化为float会损失精度
参数和陷阱
传递给函数的信息称为参数
printf中参数不对应时并不会给出警告,如果发现程序输出与预期不符,可以进行检查
程序运行情况
刷新输出
printf会将输出发送到一个叫做“缓冲区”的中间存储区域,然后缓冲区的内容再不断被发送到屏幕上
当缓冲区满、遇到换行符或者需要输入的时候,会将缓冲区的内容发送到屏幕上
练习
练习2、4、5、6四道题,目前题目依旧比较简单
简单了解了一下还没学的scanf的用法



