C 语言基础学习笔记:《C Primer Plus》

第一章 初识C语言

初识C语言

:c语言的优缺点
优点:强大的控制结构,快速,代码紧凑程序更小,可移植到其他计算机。
缺点:c语言使用指针,而涉及指针的编程错误往往难以察觉。
(有句话说的好:想拥有自由就必须时刻保持警惕。P3)

:c语言比其他语言更依赖库,因此需要一个标准库。实际上,由于缺乏官方标准,UNIX实现提供的库已成为了标准库。(P6)
第一个ANSI/ISO C标准,1989年批准ANSI C,而1990年批准ISO C,又称C89或C90,但由于ANSI先公布C标准,因此业界人士通常使用ANSI C。而委员会制定的指导原则中,最有趣的可能是:保持C的精神,委员会在表述这一精神时列出了以下几点:

  • 信任程序员
  • 不要妨碍程序员做需要做的事
  • 保持语言精练简单
  • 只提供一种方法执行一项操作
  • 让程序运行更快,即使不能保证其可移植性

而C11即2011年发布的标准出于对当前编程安全的担忧,不那么强调“信任程序员”目标了。

:C是编译型语言。理想状态下,将编写C程序的过程分解成7个步骤。(P7)

  • 1.定义程序的目标(用一般语言有思路的描述问题)
  • 2.设计程序
  • 3 编写代码(应该给自己的代码添加文字注释)
  • 4 编译(理解特定编译器报告的错误或警告信息是程序员要掌握的技能)
  • 5 运行程序
  • 6 测试和调试程序
  • 7 维护和修改程序

实际使用可能会有偏差:应根据下一个步骤的情况来调整或改进上一个步骤。
初学者经常忽略第1步和第2步,直接跳到第3步。应该养成先规划再动手编写代码的好习惯,用纸和笔记录下程序的目标和设计框架。这样再编写代码的过程中会更加得心应手,条理清晰。

四:P15提到getchar(),写嵌入式的时候用过,在这里记录一下
getchar();
getchar();
两个连用目的:第一个读取Entet键,第2个会导致程序暂停,直到用户再次按下Enter键

cc -v 可用在linux中显示你所使用的编译器及其版本

五:总结
c是强大而简洁的编程语言。它之所以流行,在于自身提供大量的实用编程工具,能很好地控制硬件。而且,与大多数其他程序相比,C程序更容易从一个系统移植到另一个系统。
c是编译型语言。c编译器和链接器是把c语言源代码转换成可执行代码的程序。

六:复习题:
1.对编程而言,可移植性意味着什么?
完美的可移植程序是,其源代码无需修改就能在不同计算机系统中成功编译的程序。
2.解释源代码文件,目标文件和可执行文件有什么区别?
源代码文件包含程序员使用的任何编程语言编写的代码。目标代码文件包含机器语言代码,它不必是完整的程序代码。可执行文件包含可执行程序的完整机器语言代码。
3.编程的7个主要步骤是什么?
①定义程序目标②设计程序③编写程序④编译程序⑤运行程序⑥测试和调试程序⑦维护和修改程序。
4.编译器的任务是什么?
编译器把源代码翻译成等价的机器语言代码。
5.链接器的任务是什么?
链接器把编译器翻译好的源代码以及库代码和启动代码组合起来,生成一个可执行程序。

七:编程练习(不是编写C代码,该练习侧重于编程过程的早期步骤)
1.你刚被MacroMuscle有限公司聘用。该公司准备进入欧洲市场,需要一个把英寸单位转换为厘米单位(1英寸=2.54厘米)的程序。该程序要提示用户输入英寸值。你的任务是定义程序目标和设计程序(编程过程的第1步和第2步)。
在这里插入图片描述

八:参考文献
Stephen Prata | 著 (姜佑 | 译).C Primer Plus.第6版 . 人民邮电出版社

第二章 C语言概述

一.示例解释

笔者有些许编程经验,能看懂示例,但本着对基础的再次巩固还是坚持看完每个字,所以有以下记录。
#include——预处理器指令
int main(void)——main()总是第一个被调用的函数;整体是组成函数的语句(类似于英语造句规则)
function a()——语句
function a()——语句 函数是C程序的构造块。
而C语言中有6种语句:1标号语句;2复合语句;3表达式语句;4选择语句;5迭代语句;6跳转语句;
(原著代码P19不写了,以上是泛泛而谈,下面摘要我感兴趣的代码的作用或者含义 。)

stdio.h ——是C编译器软件包的标准部分,它提供键盘输入和屏幕输出的支持。
int main(void) ——表示main()函数,返回值是int整型,void表示不带任何参数。(P21书中说到如果使用ANSI C之前的编译器(C89准则),请省略void,那么按照书中约定,我决定以后还是不省略了。)
int num;
num = 1; 声明变量num为int整型,且赋值为1 (记录的原因是要求自己表述准确)。
printf(“…”)——printf()是标准的C库函数,在程序中使用叫做调用函数
return 0;——其实本身这个没什么好介绍的,但是因为这个低级错误被批评过一次记得很深刻。所以这个表示C函数可以给调用方提供(或返回)一个数。目前,可暂时把该行看作是结束main()函数的要求。
(以上为概述程序中每行代码的作用,如何描述)

1: #include <stdio.h>——#符号表示C预处理器在编译器接手之前处理这条指令。include文件提供了一种方便的途径共享许多程序共有的信息。<stdio.h>是个头文件。连在一起的作用是把stdio.h文件中的所有内容都输入该行所在的位置。(实际就是一种“拷贝—粘贴”的操作。P22)
2: int main()函数——这是唯一的选择!C程序一定从main()函数开始执行(目前不考虑例外的情况)。现在记住函数是C程序的基本模块就行。而函数返回是int整型,返回给操作系统了。注意以下,main()在C90标准勉强接受,但是C99和C11标准不允许这样写。因此即使编译器允许也不要这样写。(这让我想起了gcc经常瞒天过海的一些语法错误)所以请务必坚持使用标准形式。
3: 声明把特定标识符与计算机内存中的特定位置联系起来,同时也确定了储存在某位置的信息类型或数据类型。如果变量名无法清楚地表达自身地用途,可在注释中进一步说明。这是一种良好的编程习惯和编程技巧。可以用大小写字母,数字和下划线来命名(限制了只能这几种)。但是变量名的第一个字符必须是字符或下划线,不能是数字。转折点发生在C99和C11标准为了使C国际化,允许了除英文字母意外的部分字符。由于大多编译器不支持C99标准,笔者约定自己将变量置于块的顶部。
4: 赋值语句是将右边的值赋给左边 (敲代码久了会形成肌肉记忆反而说不出来规则)
5: printf()函数里“ ”双影号的内容是实际参数,表示传递给函数的特定值。(形参是函数用于储存值的变量)这里重点说一下C语言是通过赋值运算符而不似乎赋值语句完成赋值操作。根据C标准,C语言并没有所谓的“赋值语句”,书中提到的“赋值语句”实际上是表达式语句(C语言的6中基本语句之一)。书中为“赋值表达式语句”,为了更标准的表述C,笔者与书籍约定记住这个内容。P26
6: \n换行符是一个转义序列。转义序列用于代表难以表示或无法输入的字符。如\t代表Tab键。%提醒程序,要在该处打印一个变量,d表明把变量作为十进制整数打印。printf()函数名中的 f 提醒用户,这是一种格式化打印函数。
7: 在C语言中,return语句是一种跳转语句。

二 简单程序的结构

原文中是根据示例程序教学,在这里笔者只摘录部分内容。

1.函数由函数头和函数体组成。函数头包括函数名,传入该函数的信息类型和函数的返回类型。
2.提高程序可读性的技巧:①选择有意义的函数名和写注释;②空行分隔;③每条语句各占一行。
3.记录一个表述,如下所示:
feet = 6 * fathoms;
“查找变量fathoms的值,用 6 乘以该值,并把计算结果赋给变量feet”。
4.程序的错误通常叫做bug,找出并修正错误的过程叫做调试(debug)。
5.如果编译器报错某行缺少分号,请检查上一行(很真实,实践出真知)
6.寻找bug的方法:①跟踪程序状态,一行行看;②在程序中的关键点插入printf()语句;③使用调试器(debugger)
7:关键字是C语言的词汇,不能用它们作为标识符(如:变量名)(详细表格P34)。使用关键字不当,编译器会将其视为语法错误。还有一些保留标识符,c语言已经指定它们的用途或保留它们的使用权,尽管使用不会引起语法错误,但请务必不适用。

三 本章小结

学语言得学语法,规则,词汇。

四 复习题

1 C语言的基本模块是什么?
函数

2 什么是语法错误? 写出一个英语例子和C语言的例子。
语法错误违反了组成语句或程序的规则。这是一个有语法错误的英文例子:Me speak English good.
这是一个有语法错误的C语言例子:pritnf“where are the parentheses?”;

3 什么是语义错误? 写出一个英语例子和C语言例子。
语义错误是指含义错误。这是一个有语义错误的英文例子:This sentence is excellent Czech.
这是一个由语义错误的C语言例子:thrice_n = 3 + n;

4 在main,int,function,char,=中,哪些是C语言的关键字
关键字是 int 和 char (main是一个函数名;function是函数的意思; = 是一个运算符)

五 编程练习

1:编写一个程序,第一次调用printf()函数,将自己的名和姓打印在一行。第二次调用printf()函数把名和姓分别打印在两行。最后调用两次printf(0函数,把你名和姓分成两行。(假定为 zhang san)

#include <stdio.h>
int main(void)
{
	pritnf("zhang san\n");
	printf("zhang\nsan\n");
	printf("zhang\n");
	printf("san\n");
	
	return 0;
}

2 编写一个程序把你的年龄转换成天数,并显示这两个值。这里不用考虑闰年的问题。

#include <stdio.h>
int main(void)
{
	int n,day;
	day = 365;
	
	printf("请输入你的年龄\n")scanf(%d”,&n)printf("%d岁转换成天数是%d天\n",n,n * day);

	return 0;
}

3 编写一个程序,生成以下输出:
Brazil,Russia,India,China,
India,China,
Brazil,Russia
除了main()以外,该程序还要调用两个自定义函数:一个名为br(),调用一次打印一次“Brazil,Russia”;另一个名为 ic(),调用一次打印一次“India,China”。其他内容在main()函数中完成。

#include <stdio.h>
void ic(void) //函数原型 
void br(void) //同上
int main(void)
{
	printf("Brazil,Russia,India,China\n");
	ic();  //函数调用
	br();
	
	return 0;
}
void ic(void) //定义ic()函数
{
	printf("India,China\n");
}
void br(void) //定义br()函数
{
	printf("Brazil,Russia\n");
}

4 编写一个程序,创建一个整型变量toes,并将toes设置为10.程序中还要计算toes的两倍和toes的平方。该程序应打印3个值,并分别描述以示区分。

#include <stdio.h>
int main(void)
{
	int toes;
	toes = 10;
	
	printf("toes的值为%d\ntoes的两倍为%d\ntoes的平方为%d\n",toes,toes * 2,toes * toes);
	
	return 0;
}

六 参考文献

Stephen Prata | 著 (姜佑 | 译).C Primer Plus.第6版 . 人民邮电出版社

第三章 数据和C

一 程序中的新元素

P39有示例代码,笔者只摘录部分内容。
1 float类型可以储存带小数的数字。printf()函数用 %f 打印。%.2f 表示输出的浮点数只显示小数点后面两位。
2 scanf(“%f”,&weight);表示获取从键盘输入的浮点数,把输入的值赋给weight这个变量。

二 位,字节,字

1 最小的存储单元是位(bit),可以储存“0”和“1”;
2 1字节等于八个bit,是常用的计算机存储单位(byte)
3 字(word)是设计计算机时给定的自然存储单位。(字长,1个字长只有8位)

三 整数类型和浮点数类型

1 整数以二进制存储,浮点数暂时说一个3.16E7表示3.16x(10的7次方)科学计数法。
2 计算机把浮点数分成小数部分和指数部分来表示,10进制如上,7为指数。

四 C语言基本数据类型

1 ISO C(C90)规定 int 的取值最小为16位,两个字节。一般而言,储存一个int要占用一个机器字长。(这里可以用代码测处该系统 int 整型占用几个字节)
2 声明了变量,但变量如何获得值? ①赋值②通过函数获得值(scanf())③初始化变量。第三种方法实质是在声明时赋值类似 int hot = 12;
3 printf() 打印时 转换说明的数量多出待打印值得数量时时会输出一个任意值,这个任意值是内存中得任意值,因为内存中储存的数据不同,而且编译器管理内存的位置也不同。
4 在C语言种用特定的前缀表示使用哪种进制。0x或0X表示十六进制,0(数字零)前缀表示八进制。
5 当你要显示不同进制数字的时候, %d 十进制 %o(字母欧) 八进制 %x 十六进制;另外如果要连着前缀一起使用则需要在中间加#号 %#o %#x %#X
6 科普常识: HEX表示十六进制 DEC表示十进制 OCT表示八进制 BIN表示二进制
7 char类型用于储存字符 但从技术层面看 char是整数类型 因为char类型实际上储存的是整数而不是字符 只是计算机用数字编码来处理字符 本书用ASCII编码。而标准ASCII码的范围是0-127 8位 所以char类型占一个字节(通常)。
8 char类型的字符常量和初始化 char grade = ‘A’;C语言中,用单引号括起来的单个字符被称为字符常量。编译器一发现‘A’,就会将其转换成相应的代码值。(单引号字符,双引号字符串)编码规则按照示例来即可,这样在任何系统中都不会出问题。
9 P52有转义序列表 \ 用来转义 线下课老师曾说 \ 有“还原”的功效
10 printf()函数用 %c 指明待打印的字符,一个字符变量实际上被储存为1字节的整数值。
11 C语言规定int类型不小于16位;short类型不小于16位;long类型不小于32位;
12 sizeof 是C语言的内置运算符,以字节为单位给出指定类型的大小。一般而言用 %u 转换说明匹配sizeof 的返回类型。
13 记一个表述: 下面的语句有两个 %d 转换说明,说明后面还有两个参数
printf(“%d cats ate %d cans of tuna\n”,cats,cans);

五 刷新输出

单独讲是因为我是第一次见。
printf()过程: 最初,printf()语句把输出发送到一个叫作缓冲区(buffer)的中间存储区域,然后缓冲区中的内容再不断被发送到屏幕上。C标准明确规定了何时把缓冲区中的内容发送到屏幕:当缓冲区满,遇到换行字符或需要输入的时候(从缓冲区把数据发送到屏幕或文件被称为刷新缓冲区)。
简单说: 用换行字符刷新缓冲区(“…\n”);(但是光标就得另起一行)

六 本章小结

这一章我认为是资料章节,可以当作资料翻看,所以没有认真细看。

七 参考文献

Stephen Prata | 著 (姜佑 | 译).C Primer Plus.第6版 . 人民邮电出版社

第四章 字符串和格式化输入/输出

本章目标:学会使用printf()函数和scanf()函数。会用C预处理器指令,知道如何定义,使用符号常量。
(真的有时候看这种枯燥的书很容易半途而废,但是今天我打算继续坚持下去。)

一 字符串简介

1 字符串没有专门用于储存字符串的变量类型,字符串都被储存再char类型的数组中。
(记录这条的原因是写项目的时候听从老师就这么做,但一直不知道原因。从这句话中我个人能得到的是char类型本身是用于储存字符P50的,所以认同这句话。)
2 当用char类型的数组去储存字符串时,是存在相邻的存储单元中,一个单元对应一个字符,包括字符串当中的空格。但是末尾一定多出一个\0(占一个单元,名为空字符)。C语言用空字符标记字符串的结束。它是非打印字符,ASCII码值是0。正是由于这一点 数组本身的容量一定比字符串的字符数多1才能容纳。比如char name[40];只能储存39个字符。
3 (根据P73页的代码说明)笔者摘要scanf()函数的一个局限性P74:scanf()在遇到第一个空白时不再读取输入。(一般而言就是空格,根据%s转换说明,scanf()只会读取字符串中的一个单词,而不是一整句)
4 字符串和字符区别: “x”(双引号)和‘x’(单引号)不同。前者是字符串,派生类型(char数组);后者是字符,基本类型(char)。而且字符串“x”是由两个字符组成, x 和空字符 \0

二 strlen()函数

1 strlen()函数给出字符串中的字符长度,虽然1字节储存一个字符,但是要注意与sizeof运算符区别开来(P74的代码有必要自己敲一遍。)结论是: sizeof 把字符串末尾不可见的空字符页计算在内,而strlen()函数并未将其计入,它知道在何处停止。但转换说明 %u 通用。
2 sizeof 什么时候使用圆括号,这个问题不用细究 但要知道 特定量可有可无;运算对象是类型时,必须有。

三 #define 指令

符号常量的优点: ①读长程序时,表述简单易懂;②多次使用该常量时,简化代码;③常量易浮动变化时,这样写便于调整代码;
创建符号常量:你可以声明一个变量并给它赋值置于函数顶部,但正因为是一个变量,程序可能无意间改变它的值,所以这里有一个更好的方案: C预处理器(C语言编程七个步骤的一二两步很重要)

1 通用格式: #define NAME value (为什么NAME要大写,用大写表示符号常量是C语言一贯的传统,但是要知道 小写一样可以正常运行)
2 这样定义的常量页称为 “明示常量”,这一过程被称为 编译时替换 (本书中 明示常量 = 符号常量)
3 另一个不常用的命名约定,即在名称钱带c_或k_前缀来表示常量。
4 命名规则同变量, 首字符不能为数字,限定在 大小写字母 数字 和 下划线字符。
5 #define 指令还可以定义字符和字符串常量 前者单引号 后者双引号

(C预处理器是非常有用的工具,要好好利用它。笔者在嵌入式编程里每次都用)

四 printf()函数 (输出)

printf()把整数,浮点数,字符和字符串转换成显示在屏幕上的文本。
1 因为时常用 % 来标识转换说明 所以如果要打印该符号时 %% 即可
2 printf()的转换说明修饰符(老师上课的时候没提过,一般很少用)当资料 P83
3 转换说明应该与待打印值的类型相匹配 匹配非常重要 一定要牢记于心 (重要)
4 P88的例子很重要 有必要多看几次
5 参数传递机制 程序把传入的值放入 栈 的内存区域,计算机根据 变量类型(按类型字节数)放入栈中。 然后控制转到printf()函数,根据转换说明从栈中读取值。存根据变量类型 取根据转换说明 错一个 错误传递 滚雪球
6 printf()函数的返回值可以用 x = printf(”…“);来求得 这一步既打印了信息又给变量赋值
7 不能在双引号括起来的字符串中间断行 C编译器会报错:字符串常量中有非法字符。
8 接7 给字符串断行的3个方法: ①多个printf()语句,只在最后一个加上\n换行符②使用 \ (反斜杠) 和 Enter(敲键盘) 组合来断行,使得光标移至下一行。③用多个字符串,只是在每个字符串之间添加空格隔开。例如 printf(”…“ “…” “…”);

五 scanf()函数 (输入)

scanf()把输入的字符串转换成整数,浮点数,字符或字符串,scanf()函数使用指向变量的指针。
两条简单的规则
①如果用scanf()读取基本变量类型的值,在变量名前加上一个&;
②如果用scanf()把字符串读入字符数组中,不要使用&
1 P93有scanf()的转换说明和修饰符 当作资料 ,因为实战的项目很少会用到
2 scanf()根据转换说明读取(P94划线部分,这里不再赘述),如果使用带多个转换说明的scanf()函数,C规定在第一个出错停止读取输入。
3 当scanf()把字符串放进指定数组中时,它会在字符序列的末尾加上’\0’,让数组中的内容成为一个C字符串。
4 除了%c,其它转换说明都会自动跳过待输入值前面所有的空白。
5 scanf()函数有返回值,当学会if语句和while语句 便可用scanf()的返回值来检测和处理不匹配的输入(在写项目时,这个是真的有用) (第六章的时候有用)

六 复习题

1 再次运行程序清单,但是在要求按英文书写习惯,名和姓之间有一个空格,看看情况,为什么?
在这里插入图片描述
原因: %s 在空格处停止读取,空格将被留在输入中作为下一次输入的首字符,然后scanf()会把这已读取的字符串的字符码储存在目标数组中,并在末尾加上一个空字符,但是空格后的字符串无法读取。

2 什么是空白?
空白包括空格,制表符和换行符。C语言使用空白分隔记号。scanf()使用空白分隔连续的输入项。

七 参考文献

Stephen Prata | 著 (姜佑 | 译).C Primer Plus.第6版 . 人民邮电出版社

第五章 运算符,表达式和语句

一 运算符优先级

① 乘法和除法的优先级比加法和减法高,所以先执行乘法和除法。
② 如果两个运算符的优先级相同,处理同一个运算对象时,则根据它们在语句中出现的顺序来执行。一般按照从左到右的顺序进行。(=运算符除外)
③ 最先执行圆括号的部分
④ sizeof运算符 P113 : 以字节为单位返回运算对象的大小。运算对象如果是类型,则必须用圆括号将其括起来。
⑤ % 求模运算符,对笔者而言叫 求余运算符更为贴切。只能用于整数,不能用于浮点数。
⑥ 递增运算符++ : 有前缀模式和后缀模式两种。下面有个例子
q = 2*++a 首先 a递增1,然后,2乘以a,并将结果赋给q
q = 2*a++ 首先,2乘以a,并将结果赋给q,然后,a递增1
这说明:如果a++是表达式的一部分,可将其视为“先使用a,再递增”;而++a则表示“先递增a,再使用。” 下面是笔者随手写的例子
在这里插入图片描述
感兴趣,可以试试结果是什么。

勿要自作聪明,请遵循以下规则,避免问题产生

  • 如果一个变量出现在一个函数的多个参数中,不要对该变量使用递增或递减运算符。
  • 如果一个变量多次出现再一个表达式中,不要对该变量使用递增或递减运算符。
二 表达式和语句

① C表达式的一个最重要的特性是,每个表达式都有一个值。要获得这个值,必须根据运算符优先级规定的顺序来执行操作。
② C把末尾加上一个分号的表达式都看作是一条语句。最简单的语句是空语句 ;(一个分号)
③ 声明创建了名称和类型,并为其分配内存位置。

三 类型转换

① 由于都是从较小类型转换为较大类型,所以这些转换被称为升级。
② 涉及两种类型的运算,两个值被分别转换成两种类型的更高级别。
③ 类型的级别从高至低依次是 long double,double,float,unsigned long long,long long时,unsigned long,long,unsigned int,int。例外的情况是,当 long 和 int 的大小相同时,unsigned int 比 long 的级别高。

一般而言,不应该混合使用类型。

四 P126页有个错误 应改成256 P127总结了运算符
五 带参数的函数

① 可以说形参是变量,实参是函数调用提供的值,实参被赋给相应的形参。
② 例如 void pound() 函数声明只指明了函数名和返回类型;

六 总结

如果你不了解运算符的优先级和结合律,写出的表达式可能不合法或者表达式的值与预期不符。不要养成依赖自动类型转换的习惯,应该显示选择合适的类型或使用强制类型转换,这样,就不用担心出现不必要的类型转换。

七 参考文献

Stephen Prata | 著 (姜佑 | 译).C Primer Plus.第6版 . 人民邮电出版社

第六章 C控制语句: 循环

关键字:for,while,do,while

scanf()函数

scanf()函数返回值:例如scanf( %d%d ,a,b); 函数返回值为int型。如果a和b都被成功读入,那么scanf的返回值就是2; 如果只有a被成功读入,返回值为1; 如果a和b都未被成功读入,返回值为0; 如果遇到错误或遇到end of file,返回值为EOF。 三种结果 成功项数 未成功 0 错误 EOF(等于-1);
(可以利用这一点来增加判定判断scanf是否获取的内容是程序想要的)
scanf 会跳过空白字符

status = scanf("%1d",&num);
while(status == 1)
{
	/*循环行为*/
	status = scanf("%1d",&num);
}
//可以用这些代码替代:				//使用scanf()的两种不同特性
while(scanf("%1d",&num) == 1)
{
	/*循环行为*/
}
//第二种方法的伪代码是
// 当获取值和判断值都成功
//	处理该值

入口条件循环 while 循环

while循环的通用形式如下
while(expressione link.)
statement; //分号结尾,循环结束;加了花括号以括号为准
每次循环都被称为一次迭代(iteration link.)

程序员在表达while循环时候 while(goats)替换while(goats!=0), 因为表达式 goats!=0和goats都只有在goats的值为0才为0或假。
C语言把所有非零值都视为真。 C99标准专门新增了_Bool类型,称为布尔变量_Bool 类型的变量只能储存1或0;如果其它变量值赋给_Bool类型,该变量会变成1。

关系运算符的优先级比算数运算符的优先级低,比赋值优先级高

入口条件循环 for 循环

for(初始化;测试条件;执行更新)
注意: 只对第一个表达式求值一次或执行一次 ,不单单是进行初始化
注意几个其他赋值运算符:+=,-=,*=,/=,&=
a += b; 等价于 a = a + b;这样做的目的可以使代码紧凑,生成的机器代码更高效,可以塞进for循环
逗号运算符:逗号运算符把两个表达式连接成一个表达式,并保证最左边的表达式最先求值。

出口条件循环 do while 循环

下面是通用形式
do
	statement
while(expression);
该循环必须执行一次,比较适合执行一次就判断的场合;

如何选择循环

看自己使用频率和喜欢,测试条件合适 用谁都行,多练习积攒经验。

嵌套循环

想象成坐标轴,一个循环处理x轴,一个循环处理y轴。

数组简介

scanf("%d",&a[1];
表示把一个值读入数组的第2个元素.数组的初始下标为0;
用于识别数组元素的数字被称为 下标
但是C编译器不会检查数组的下标是否正确。
而在用数组存放字符串时,一定要保证多出一个存放空字符‘\0’的位置。
数组的元素依次储存在内存中相邻的位置。

循环注意

  • 注意循环的测试条件要能使循环结束;
  • 确保循环测试中的值在首次使用之前已初始化
  • 确保循环在每次迭代都更新测试的值

使用函数涉及3个步骤

  • 通过函数原型声明函数
  • 在程序中通过函数调用使用函数
  • 定义函数

参考文献

Stephen Prata | 著 (姜佑 | 译).C Primer Plus.第6版 . 人民邮电出版社

第七章 C控制语句:分支和跳转

关键字

getchar()和putchar()

字符输入gerchar();输出函数putchar();
例如下面的语句读取下一个字符输入,并把该字符的值赋给变量ch:
ch = getchar(); 其实等价于scanf("%c",&ch);

putchar()负责打印它的参数。例如,下面的语句把之前赋给ch的值作为字符打印出来:
putchar(ch); 等同于printf(“%c”,ch);
这些函数只处理字符,所以它们比更通用的scanf()和printf()函数 更快,更简洁,而且不需要转换说明。

这两个函数通常定义在 <stdio.h>头文件中。(通常是预处理宏,而不是真正的函数)

ch = getchar();
while(ch != '\n')	 当一行尚未结束时
{
	...
	ch = getchar();  获取下一个字符
}
可以替换成下面形式的循环
while((ch = getchat()) != '\n')		C特有的编程风格————把两个行为合并成一个表达式
{
	...  		处理字符
}

else 与 if 配对规则

如果没有花括号,else 与离它最近的 if 匹配,除非最近的 if 被花括号括起来。

逻辑运算符

逻辑运算符优先级低于关系运算符,不必在子表达式两侧加圆括号;
与 && 或 || 非 !
优先级难背,不如随时准备打圆括号

求值顺序

逻辑表达式的求值顺序是从左往右,一旦发现有使整个表达式为假的因素。立即停止求值。

范围

许多代码都用范围测试来确定一个字符是否为小写字母
例如 if (ch>=‘a’ && ch <= ‘z’)printf("\n");
而现在可用 islower() 函数来求,头文件是<ctype.h>
例如 if(islower(ch)) printf("\n");

一个统计单词的程序



循环辅助 continue 和 break

执行continue时,下一个被求值得表达式是循环测试条件。
break跳出最近的i一个循环。

多重选择 switch 和 break

break 语句可用于循环和switch中,但是continue只能用于循环中

它包括了多个 case 标签,以及最多一个 default 标签。
switch括号里的值,按顺序和 case 标签中的常量表达式做比较。
如果表达式的值匹配其中的某个 case 常量,程序流就会跳转到该 case 标签后面的语句。
如果没有匹配的 case 常量,程序流就会跳转到 default 标签后的语句(如果存在 default 标签)。
expression和case标签都必须是整数值(包括char类型),标签必须是常量或完全由常量组成的表达式
switch(expression)
{
	case 1:statement;
		break;
	case 2:statement;
		break;
	default:statement;
}

举个栗子
处理用户所选择的菜单命令
声明用到的其他函数
int menu( void );             // 输出菜单,并返回用户键入的字符
void action1( void ),
     action2( void );

switch ( menu() )             // 根据menu()的结果跳转
{
   case 'a':
   case 'A': action1();               // 执行动作1
             break;           // 不执行任何其他动作
   case 'b':
   case 'B': action2();       // 执行动作2
             break;           // 不执行默认的动作
   default:  putchar( '\a' ); // 如果没有识别到任何命令,输出一个警告信息
}

猜你喜欢

转载自blog.csdn.net/GameStrategist/article/details/105632927
今日推荐