C语言笔记

第三章

数据和C

image-20220129210403069

image-20220129210430389

image-20220129210452764

image-20220129210508819

因为在任何区间内(如,1.0 到 2.0 之间)都存在无穷多个实数,所以

计算机的浮点数不能表示区间内所有的值。浮点数通常只是实际值的近似

值。例如,7.0可能被储存为浮点值6.99999

image-20220129210601692

image-20220129210636376

image-20220129210652314

image-20220129210708679

第四章

1、字符串

1、字符串是一个或多个字符的序列,双引号告诉编译器它括起来的是字符串

2、字符串由%s表示

3、字符串的实质是char类型数组

2、const限定符

1、const用于限定一个变量为只读

2、在指针针中若const在*之前表示不能通过指针修改若在 *之后表明限定该指针只能指向该数组

3、printf()函数

1、printf()打印数据的指令要与待打印数据的类型相匹配

2、printf( 格式字符串, 待打印项1, 待打印项2,…);

待打印项1、待打印项2等都是要打印的项。它们可以是变量、常量,甚

至是在打印之前先要计算的表达式。第3章提到过,格式字符串应包含每个

待打印项对应的转换说明。

3、 格式字符串中的转换说明一定要与后面的每个项相匹配

4、由于 printf()函数使用%符号来标识转换说明打印%需要2个%

5、printf()的返回值是其打印输出功能的附带用途,通常很少用到,但在检

查输出错误时可能会用到

6、有时,printf()语句太长,在屏幕上不方便阅读。如果空白(空格、制表

符、换行符)仅用于分隔不同的部分,C 编译器会忽略它们。因此,一条语

句可以写成多行,只需在不同部分之间输入空白即可

7、C编译器会报错:字符串常量中有非法字符。在字符串中,可以使用\n

来表示换行字符,但是不能通过按下Enter(或Return)键产生实际的换行

scanf()函数

1、scanf()中的格式 字符串表明字符输入流的目标数据类型

2、如果用scanf()读取基本变量类型的值,在变量名前加上一个&;

如果用scanf()把字符串读入字符数组中,不要使用&。

3、scanf()函数使用空白(换行符、制表符和空格)把输入分成多个字段。

在依次把转换说明和字段匹配时跳过空白

4、scanf()函数所用的转换说明与printf()函数几乎相同。主要的区别是,对

于float类型和double类型,printf()都使用%f、%e、%E、%g和%G转换说

5、scanf()函数允许把普通字符放在格式字符串中。除空格字符外的普通字

符必须与输入字符串严格匹配

第五章

基本运算符

赋值运算符

1、在C语言中,=并不意味着“相等”,而是一个赋值运算符,=号左侧是一个变量名,右侧是赋

给该变量的值,符号=被称为赋值运算符。

加法运算符

1、加法运算符用于加法运算,使其两侧的值相加

2、相加的值(运算对象)可以是变量,也可以是常量

减法运算符

1、减法运算符用于减法运算,使其左侧的数减去右侧的数

2、+和-运算符都被称为二元运算符,即这些运算符需要

两个运算对象才能完成操作

符号运算符

1、减号还可用于标明或改变一个值的代数符号

2、符号运算符是一元运算符

3、一元运算符只需要一个运算对象

乘法运算符

1、用*表示

除法运算符

1、C使用符号/来表示除法。/左侧的值是被除数,右侧的值是除数

2、整数除法和浮点数除法不同。浮点数除法的结果是浮点数,而整数除法

的结果是整数

运算符优先级

其他运算符

sizeof运算符和size_t类型

1、,sizeof运算符以字节为单位返回运算对象的大小

2、运算对象可以是具体的数据对象或类型

3、如果运算对象是类型则必须用圆括号将其括起来

4、sizeof 返回 size_t 类型的值

求模运算符

1、求模运算符用于整数运算

2、求模运算符给出其左侧整数除以右侧整数的余数

3、求模运算符只能用于整数,不能用于浮点数

4、求模运算符常用于控制程序流

递增运算符

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HVSEhKqa-1647655070605)(FIVE.assets/image-20220111200741095.png)]

image-20220111200805583

递减运算符

与递增运算符同理

表达式

1、表达式由运算符和运算对象组成

2、运算对象可以是常量、变量或二者的组合

3、C 表达式的一个最重要的特性是,每个表达式都有一个值

语句

1、语句是C程序的基本构建块,一条语句相当于一条完整的计算机指令

2、C把末尾加上一个分号的表达式都看作是一条语句

image-20220112141240520

3、复合语句是用花括号括起来的一条或多条语句,复合语句也称为块

类型转换

1.当类型转换出现在表达式时,无论是unsigned还是signed的char和short都会被自动转换成int,如有必要会被转换成unsigned int

2.涉及两种类型的运算,两个值会被分别转换成两种类型的更高级别

3.类型的级别从高至低依次是long double、double、float、unsignedlong 、long、long long、unsigned long、long、unsigned int、int

4.在赋值表达式语句中,计算的最终结果会被转换成被赋值变量的类型

5.当作为函数参数传递时,char和short被转换成int,float被转换成double

第六章

while

1、while循环的通用形式如下:

while ( expression )

statement

statement部分可以是以分号结尾的简单语句,也可以是用花括号括起来

的复合语句。

2、expression是值之间的比较,可以使用任何表达式。如果expression为真

(或者更一般地说,非零),执行 statement部分一次,然后再次判断

expression。在expression为假(0)之前,循环的判断和执行一直重复进行。

每次循环都被称为一次迭代

3、while循环有一点非常重要:在构建while循环时,必须让测试表达式的

值有变化,表达式最终要为假。否则,循环就不会终止

4、要明确一点:只有在对测试条件求值时,才决定是终止还是继续循环

5、while循环是使用入口条件的有条件循环,若入口条件为假则不会执行循环

6、使用while时,要牢记一点:只有在测试条件后面的单独语句(简单语

句或复合语句)才是循环部分

7、即使while语句本身使用复合语句,在语句构成上,它也是一条

单独的语句

8、对C而言,表达式为真的值是1,表达式为假的值是0。

9、在创建一个重复执行固定次数的循环中涉及了3个行为:

1.必须初始化计数器;

2.计数器与有限的值作比较;

3.每次循环时递增计数器。

for循环

1、for循环把初始化、测试和更新组合在一处。

2、关键字for后面的圆括号中有3个表达式,分别用两个分号隔开。第1个

表达式是初始化,只会在for循环开始时执行一次。第 2 个表达式是测试条

件,在执行循环之前对表达式求值。如果表达式为假(本例中,count大于

NUMBER时),循环结束。第3个表达式执行更新,在每次循环结束时求

值。

3、for循环中的3个表达式可以是不同的变量

4、第1个表达式不一定是给变量赋初值,也可以使用printf(),在执

行循环的其他部分之前,只对第1个表达式求值一次或执行一次

5、for语句使用3个表达式控制循环过程,分别用分号隔开。initialize表达

式在执行for语句之前只执行一次;然后对test表达式求值,如果表达式为真

(或非零),执行循环一次;接着对update表达式求值,并再次检查test表达

6、for语句是一种入口条件循环,即在执行循环之前就决定了是否执行循

环。因此,for循环可能一次都不执行

运算符

1、逗号运算符扩展了for循环的灵活性,以便在循环头中包含更多的表达

2、整个逗号表达式的值是右侧项的值

3、+= 把右侧的值加到左侧的变量上

-= 从左侧的变量中减去右侧的值

*= 把左侧的变量乘以右侧的值

/= 把左侧的变量除以右侧的值

%= 左侧变量除以右侧值得到的余数

do while

1、采用出口条件循 ,即在循环的每次迭代之后检查测试条件,这保证

了至少执行循环体中的内容一次

2、do

statement

while ( expression );

3、do while循环以分号结尾

嵌套循环

1、嵌套循环指在一个循环内包含另一个循环。嵌套循环常

用于按行和列显示数据,也就是说,一个循环处理一行中的所有列,另一个

循环处理所有的行

第七章

if

1、if ( expression )

statement

2、如果对expression求值为真(非0),则执行statement;否则,跳过

statement

3、即使if语句由复合语句构成,整个if语句仍被视为一条语句

ifelse

1、if ( expression )

statement1

else

statement2

2、如果expression为真(非0),则执行statement1;如果expression为假或

0,则执行else后面的statement2

3、if语句用于选择是否执行一个行为,而else if语句用于在两个行为之间

选择

4、规则是,如果没有花括号,else与离它最近的if匹配,除非最近的if被花

括号括起来

5、从技术角度看,if else语句作为一条单独的语句,不必使用花括号。外

层if也是一条单独的语句,也不必使用花括号。但是,当语句太长时,使用

花括号能提高代码的可读性,而且还可防止今后在if循环中添加其他语句时

忘记加花括号

getchar()putchar()

1、getchar()函数不带任何参数,它从输入队列中返回下一个字符

2、putchar()函数打印它的参数

3、由于这些函数只处理字符,所以它们比更通用的scanf()和printf()函数更

快、更简洁

4、注意 getchar()和 putchar()不需要转换说明,因为它们只

处理字符

逻辑运算

1、C保证逻辑表达式的求值顺序是从左往右

2、&&和||运算符都是序列点,所以程序在从一个运算对象执行到下

一个运算对象之前,所有的副作用都会生效

2、C 保证一旦发现某个元素让整个表达式无效,便立即停止求值

3、当且仅当expression1和expression2都为真,expression1 && expression2才

为真。如果 expression1 或 expression2 为真,expression1 || expression2 为

真。如果expression为假,!expression则为真,反之亦然

4、&&运算符可用于测试范围

条件运算符

1、expression1 ? expression2 : expression3

2、如果 expression1 为真(非 0),那么整个条件表达式的值与 expression2

的值相同;如果expression1为假(0),那么整个条件表达式的值与

expression3的值相同

Switch

1、可以在switch语句中使用多重case标签

2、程序根据expression的值跳转至相应的case标签处。然后,执行剩下的所

有语句,除非执行到break语句进行重定向

3、expression和case标签都必须是整数值(包括char类型),标签必须是常量或完全由常量组成的表达式)

第八章

缓冲区

1、缓冲分为两类:完全缓冲I/O和行缓冲I/O。完全缓冲输入指的是当缓冲

区被填满时才刷新缓冲区(内容被发送至目的地),通常出现在文件输入

中。缓冲区的大小取决于系统,常见的大小是 512 字节和 4096字节。行缓

冲I/O指的是在出现换行符时刷新缓冲区。键盘输入通常是行缓冲输入,所

以在按下Enter键后才刷新缓冲区。

2、ANSI C决定把缓冲输入作为标准的原因是:一些计算机不允许无缓冲

输入

文件

1、当编译储存在名为 echo.c 文件中的程序时,编译器打开echo.c文件并读取其中的内容。当

编译器处理完后,会关闭该文件。其他程序,例如文字处理器,不仅要打

开、读取和关闭文件,还要把数据写入文件

2、从较低层面上,C可以使用主机操作系统的基本文件工具直接处

理文件,这些直接调用操作系统的函数被称为底层 I/O

3、从概念上看,C程序处理的是流而不是直接处理文件

4、流是一个实际输入或输出映射的理想化数据流。这意味着不同属性和不同种类的

输入,由属性更统一的流来表示

重定向

1、重定向的一个主要问题与操作系统有关,与C无关

2、重定向运算符连接一个可执行程序(包括标准操作系统命令)和一个数

据文件,不能用于连接一个数据文件和另一个数据文件,也不能用于连接一

个程序和另一个程序

3、使用重定向运算符不能读取多个文件的输入,也不能把输出定向至多个

文件

4、通常,文件名和运算符之间的空格不是必须的

5、如果不使用命令行环境,也可以使用重定向

输入验证

1、main()函数管理程序流,为其他函数委派任务

2、虽然输入流由字符组成,但是也可以设置scanf()函数把它们转换成数

值。简而言之,输入由字符组成,但是scanf()可以把输入转换成整数值或浮

点数值

菜单浏览

1、许多计算机程序都把菜单作为用户界面的一部分

2、当你决定实现这个程序时,就要开始考虑如何让程序顺利运行(顺利运

行指的是,处理正确输入和错误输入时都能顺利运行)

3、C程序把输入作为传入的字节流。getchar()函数把每个字符解释成一个

字符编码。scanf()函数以同样的方式看待输入,但是根据转换说明,它可以

把字符输入转换成数值。许多操作系统都提供重定向,允许用文件代替键盘

输入,用文件代替显示器输出

image-20220121145238442

第九章

函数

1、函数是完成特定任务的独立程序代码单元

2、函数原型)告诉编译器函数的类型;函数调用表明在此处执行函数;

函数定义明确地指定了函数要做什么

3、函数和变量一样,有多种类型。任何程序在使用函数之前都要声明该函

数的类型

4、一般而言,函数原型指明了函数的返回值类型和函数接受的参数类型。

这些信息称为该函数的签名

5、在使用函数之前,要用ANSI C形式声明函数原型

image-20220122163715605

image-20220122170626312

image-20220122172513630

image-20220123101857282

6、关键字return后面的表达式的值就是函数的返回值

7、返回值不仅可以赋给变量,也可以被用作表达式的一部分

8、返回值不一定是变量的值,也可以是任意表达式的值

递归

1、C允许函数调用它自己,这种调用过程称为递归

2、可以使用循环的地方通常都可以使用递归。有时用循环解决问题比较

好,但有时用递归更好。递归方案更简洁,但效率却没有循环高

image-20220123102200133

3、每次函数调用都会返回一次。当函数执行完毕后,控制权将被传

回上一级递归。程序必须按顺序逐级返回递归

4、递归函数中位于递归调用之前的语句,均按被调函数的顺序执

5、递归函数中位于递归调用之后的语句,均按被调函数相反的顺序

执行

6、虽然每级递归都有自己的变量,但是并没有拷贝函数的代码。程

序按顺序执行函数中的代码,而递归调用就相当于又从头开始执行函数的代

7、递归函数必须包含能让递归调用停止的语句

image-20220123102537855

&运算符

1、一元&运算符给出变量的存储地址。如果pooh是变量名,那么&pooh是

变量的地址

初识指针

1、从根本上看,指针是一个值为内存地址的变量

2、要创建指针变量,先要声明指针变量的类型

3、后跟一个变量名时,&给出该变量的地址

4、后跟一个指针名或地址时,*给出储存在指针指向地址上的值

5、声明指针变量时必须指定指针所指向变量的类型,因为不同的变量类型占用不同的存储空间,一些指针操作要求知道操

作对象的大小。另外,程序必须知道储存在指定地址上的数据类型。long和float可能占用相同的存储空间,但是它们储存数字却大相径庭

6、类型说明符表明了指针所指向对象的类型,星号(*)表明声明的变量

是一个指针。int * pi;声明的意思是pi是一个指针,*pi是int类型

image-20220124111100094

7、*和指针名之间的空格可有可无。通常,程序员在声明时使用空格,在解引用变量时省略空格

image-20220124110346564

第十章

数组

1、数组由数据类型相同的一系列元素组成。需要使用数组时,通过声明数组告诉编译器数组中内含多少元素和这些元素的类型。编译

器根据这些信息正确地创建数组。普通变量可以使用的类型,数组元素都可以用

2、要访问数组中的元素,通过使用数组下标数(也称为索引)表示数组中

的各元素。数组元素的编号从0开始

3、用以逗号分隔的值列表(用花括号括起来)来初始化数组,

各值之间用逗号分隔。在逗号和值之间可以使用空格

4、有时需要把数组设置为只读。这样,程序只能从数组中检索值,不能把

新值写入数组。要创建只读数组,应该用const声明和初始化数组

5、使用数组前必须先初始化它

6、如果初始化数组时省略方括号中的数字,编译器会根据初始化列表中的

项数来确定数组的大小

7、对于一般的初始化,在初始化一个元素后,未初始化的元素都会被设置

为0

8、在使用数组时,要防止数组下标超出边界。也就是说,必须确保下标是

有效的值

多维数组

image-20220125084348888

1、初始化二维数组是建立在初始化一维数组的基础上

2、初始化时也可省略内部的花括号,只保留最外面的一对花括号。只要保

证初始化的数值个数正确,初始化的效果与上面相同。但是如果初始化的数

值不够,则按照先后顺序逐行初始化,直到用完所有的值。后面没有值初始

化的元素被统一初始化为0

image-20220125084514552

3、可以把一维数组想象成一行数据,把二维数组想象成数据表,把三维数

组想象成一叠数据表

image-20220125092123868

image-20220126104006150

image-20220126110235492

指针

1、指针提供一种以符号形式使用地址的方法。因为计算机的硬件指令非常依赖地址,指针在某种程度上把程序员想要传达的指令

以更接近机器的方式表达。因此,使用指针的程序更有效率

image-20220126215812407

2、可以更清楚地定义指向int的指针、指向float的指针,以及指向其他

数据对象的指针

3、指针的值是它所指向对象的地址。地址的表示方式依赖于计算机内部的硬件

4、可以使用指针标识数组的元素和获得元素的值

image-20220126220231415

image-20220126220456038

函数数组指针

1、既然能使用指针表示数组名,也可以用数组名表示指针

2、int *ar形式和int ar[]形式都表示ar是一个指向int的指针。但是,int ar[]只

能用于声明形式参数。第2种形式intar[])提醒读者指针ar指向的不仅仅

一个int类型值,还是一个int类型数组的元素

3、因为数组名是该数组首元素的地址,作为实际参数的数组名要求形式参

数是一个与之匹配的指针

4、一元运算符*和++的优先级相同,但结合律是从右往左,所以start++先

求值,然后才是*start。也就是说,指针start先递增后指向。使用后缀形式

(即start++而不是++start)意味着先把指针指向位置上的值加到total上,然

后再递增指针

5、ar[i]和*(ar+1)这两个表达式都是等价的

6、赋值:可以把地址赋给指针。例如,用数组名、带地址运算符(&)的

变量名、另一个指针进行赋值

7、解引用:*运算符给出指针指向地址上储存的值

8、取址:和所有变量一样,指针变量也有自己的地址和值。对指针而言,

&运算符给出指针本身的地址

9、指针与整数相加:可以使用+运算符把指针与整数相加,或整数与指针

相加

10、递增指针:递增指向数组元素的指针可以让该指针移动至数组的下一个

元素

image-20220128105228792

11、指针减去一个整数:可以使用-运算符从一个指针中减去一个整数。指

针必须是第1个运算对象,整数是第 2 个运算对象

12、指针求差:可以计算两个指针的差值

image-20220128105927969

image-20220128114523539

第十一章

表示字符串和字符串I/O

1、用双引号括起来的内容称为字符串字面量也叫作字符

串常量。双引号中的字符和编译器自动加入末尾的\0字

符,都作为字符串储存在内存中

2、从ANSI C标准起,如果字符串字面量之间没有间隔,或者用空白字符

分隔,C会将其视为串联起来的字符串字面量

3、如果要在字符串内部使用双引号,必须在双引号前面加上一个反斜杠

4、字符串常量属于静态存储类别这说明如果在函

数中使用字符串常量,该字符串只会被储存一次,在整个程序的生命期内存

在,即使函数被调用多次。用双引号括起来的内容被视为指向该字符串储存

位置的指针。这类似于把数组名作为指向该数组位置的指针

5、定义字符串数组时,必须让编译器知道需要多少空间

6、在指定数组大小时,要确保数组的元素个数至少比字符串长度多1

image-20220207112644550

image-20220207112908203

字符串输入

1、要做的第 1 件事是分配空间,以储存稍后读入的字符串

2、过去通常用fgets()来代替gets(),fgets()函数稍微复杂些,在处理输入方

面与gets()略有不同。C11标准新增的gets_s()函数也可代替gets()。该函数与

gets()函数更接近,而且可以替换现有代码中的gets()。但是,它是stdio.h输

入/输出函数系列中的可选扩展,所以支持C11的编译器也不一定支持它

3、fgets()函数通过第2个参数限制读入的字符数来解决溢出的问题

4、fgets()函数的第2个参数指明了读入字符的最大数量。如果该参数的值

是n,那么fgets()将读入n-1个字符,或者读到遇到的第一个换行符为止

5、如果fgets()读到一个换行符,会把它储存在字符串中。这点与gets()不

同,gets()会丢弃换行符

6、fgets()函数的第3 个参数指明要读入的文件。如果读入从键盘输入的数

据,则以stdin(标准输入)作为参数,该标识符定义在stdio.h中

7、空指针(或NULL)有一个值,该值不会与任何数据的有效地址对应。

通常,函数使用它返回一个有效地址表示某些特殊情况发生,例如遇到文件

结尾或未能按预期执行

8、如果gets_s()读到最大字符数都没有读到换行符,会执行以下几步。首

先把目标数组中的首字符设置为空字符,读取并丢弃随后的输入直至读到换

行符或文件结尾,然后返回空指针。接着,调用依赖实现的“处理函数”(或

你选择的其他函数),可能会中止或退出程序

image-20220208134420280

image-20220208140557152

image-20220208141803615

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值