程序设计入门——C语言
文章目录
程序设计入门——C语言
一、程序设计与C语言
1.计算机和编程语言
1.计算机与编程语言:计算机怎么做事情的,编程语言是什么
- 人做事情:只需要被告诉要做什么事——what to do
- 计算机做事:需要被告诉如何去做这件事情——how to do
我们要让计算机做计算,就需要找出计算的步骤,然后用编程语言写出来。计算机做的所有事情都叫做计算。计算的步骤就是算法。
计算机只能看懂机器语言,如二进制、十六进制,
程序代码是告诉计算机做这件事情的步骤,
计算的步骤就是算法。
2.计算机的思维方式:重复是计算机最擅长的
计算机解方程,最初就是枚举,比如计算x-5=0时,计算机就从x=0,1,2这样一直代入式子中,直到代入5时成立,就算出来了。现在的计算机都是懂得用公式的,比如解一元二次方程,直接套入公式求解出来。只有那些没有通用公式的才得用数值代入法求解。
程序的执行:
- 解释:借助一个程序,那个程序能试图理解你的程序,然后按照你的要求执行
- 编译:借助一个程序,就像一个翻译,把你的程序翻译成计算机真正能懂的语言——机器语言——写的程序,然后,这个机器语言写的程序就能直接执行了
对于编程语言来说,语言本身是没有解释和编译的区分的,任何语言既可以解释执行也可以编译执行,只是传统和常用的习惯而已,也有人做了C语言的解释器。
2.C语言
1.为什么是C
C语言在工业界有重要的地位,在很多领域无可替代,几乎所有和硬件打交道的地方都得要用C语言。
2.简单历史
C语言是伴随着Unix一起起来的,作为一个有着40多年历史的语言,它是当代很多新兴语言的基础参考体系,但是它也无可避免地带着1970年代的时代烙印。今天的编程语言,基本上都是一家主持的,标准统一,编译运行环境单纯。而C语言只有所谓的标准,每个实现C语言编译器和运行库的厂家都在往里面加入自己的方言。
二、计算
部分运算的需要:
- 有办法输入数字
- 有地方放输入的数字
- 输入的数字能参与运算
1.变量
1.变量定义:变量是做什么的,如何定义一个变量
变量是一个保存数据的地方,当我们需要在程序里保存数据时,比如计算找零时要记录用户输入的价格,就需要一个变量来保存它。用一个变量保存了数据,它才能参加到后面的计算中,比如计算找零。
变量定义的一般形式:
<类型名称> <变量名称>;
如:Int price; int amount; int price,amount;
变量的名称叫“标识符”,意思是用来识别这个和那个的不同的名字。
- 标识符只能由字母、数字、下划线组成
- 数字不能放在第一位
- C语言中的关键字/保留字(如int、cin等)不能用做标识符
2.变量赋值与初始化,以及如何读输入的数字
int price=0; price=0是一个式子,这里的“=”是一个赋值运算符,表示将“=”右边的值赋给左边的变量。
3.关于scanf
C、C++的输入是以行为单位进行的,而行的结束的标志就是你按下了回车键。在按下回车之前,程序不会读到任何东西。
scanf("%d,%lf",&a,&b); scanf("%d %lf",&a,&b);
scanf双引号里面的东西不能随便写,是严格一一对应的,中间用逗号隔开,在黑窗输入时数值之间就以逗号隔开,中间用空格隔开,在黑窗输入时数值之间就以空格隔开。或者直接输入一个回车一下。
4.常量vs变量:不变的量是常量
const int AMOUNT=100;
定义常量的好处:
- 常量的变量名一般默认为全大写字母,看到变量名易于理解其含义,如:AMOUNT
- 易于修改,需要更换不同值时,只需要把最前面定义的常量值修改即可
2.数据类型
浮点数:整数运算的结果只有整数部分,不然就要用浮点数
10和10.0在C中是完全不同的数,10.0是浮点数。
浮点数是带小数点的数值,浮点这个词的本意就是指小数点是浮动的,意思是小数点在这个数的第几位是可以变动的,浮点数是计算机内部表达非整数(包括分数、无理数)的一种方式。定点数是确定的在一个数的第几位,比如永远在一个数的第四位或者第五位。浮点和定点都是计算机中表达有小数点的数的方式。C语言中用浮点数来表达所有的带小数点的数。
运算符两边只要有一边是浮点数,结果就是浮点数。
double 双精度浮点数,用scanf输入是%lf,用printf输出是%lf或%f
单精度浮点数8位有效数字,双精度浮点数16位有效数字,当小数过长超过有效位数时,会按照四舍五入自动进位,%f和%lf都是默认输出小数点后6位,如果需要多输出,强指定就可以了,如 printf(“%.15lf”,a);可以输出小数点后15位。
3.表达式
1.表达式:运算符和算子,取余计算,程序就是数据加计算
- 运算符(ooerator)是指进行运算的动作,比如加法运算符“+”,减法运算符“-”
- 算子(operand)是指参与运算的值,这个值可能是常数,也可能是变量,还可能是一个方法的返回值
运算符“%”是取余
2.运算符优先级:优先级、结合关系、赋值运算符
就是正常的先算乘除取余,后算加减,但要注意单目运算,单目±自右向左,如单目不变:a *+b、单目取负:a *-b。3 *+5=15,3 *-5=-15,3±5=-2
赋值运算也是自右向左,a=b=6→a=(b=6),赋值优先级比所有四则运算都低
单目运算符优先级高于双目运算符
3.交换变量:如何交换两个变量的值,顺便看下Dev的调试功能
交换两变量的值可以引入中间变量
4.复合赋值和递增递减:这是两类有历史也有争议的运算符
- 复合赋值:+=、-=、*=、/=
- 递增递减:++、–,有前缀后缀两种形式,作用效果是先使用再加减还是先加减再使用
三、判断与循环
1.判断
1.做判断:if语句根据条件决定做不做
取决于小括号里面是0还是1
2.判断的条件:关系运算,做比较的运算符
当两个值的关系符合关系运算符的预期时,关系运算的结果为1,否则为0
所有的关系运算符的优先级都比算术运算的低,但是比赋值运算高(7>=3+4、int r=a>0)
判断是否相等的==和!=的优先级比其他关系符还低
3.找零计算器:判断,注释,流程图
4.否则的话:如果条件不成立呢?
写代码,有的时候我们更看重的是,你能不能让更多的人读懂你的代码
5.if语句再探:if和else后面也可以没有{}而是一条语句
但是建议一句话也写上大括号{}
2.循环
1.循环:有些事情就得用循环才能解决
2.while循环:就像if一样,条件满足就不断地做后面的句子
输出调试法比较适合调试交互复杂的程序,但是在最后提交代码时,记得把调试代码注释掉。
3.do-while循环:不管三七二十一,先做循环内的句
4.for循环
for循环像一个计数循环:先设定一个计数器并初始赋值,然后在计数器到达某值之前,重复执行循环体。每执行一轮循环,计数器值以一定步进行调整,如+1
5.循环的选择
for(初始动作;条件;每轮的动作){
}
for中的每一个表达式都是可以省略的,for(;条件;) == while(条件)
如果有固定次数,用for;
如果必须执行一次,用do_while;
其他情况用while
四、进一步的判断与循环
1.逻辑类型和运算
1.逻辑类型
布尔类型bool,布尔型变量在C++11里面可以不用写头文件
2.逻辑运算
优先级 ! > && > ||
所学运算符的优先级:
3.条件运算和逗号运算
a=(条件)?条件满足时的值:条件不满足时的值;
我们不希望你使用嵌套的条件表达式,即一个式子好几个问号。
逗号运算符基本只在for中使用,如:for(i=0,j=10;i<j;i++,j–)
这样一想,也便于助记If、for、while的()里面的条件之间都是用分号;隔开
i=(3+4,5+6);→i=11
2.级联和嵌套的判断
1.嵌套的if-else
else总是和最近的那个if匹配,在if或else后面总是用大括号,即使只有一条语句。
2.级联的if-else
}else if(){
}//else if中间有空格
3.多路分支
switch-case
4.循环的例子
1.循环计算
2.算平均数
3.猜数
4.整数求逆
5.判断和循环常见的错误
- if 忘了大括号。永远在if和else后面加上大括号,哪怕就一句。
- if 后面加分号。
- 错误使用==和=。
风格是三观,大公司会有自己的规范要求,进了企业按照要求做就好
五、循环控制
1.循环控制
break:跳出循环,即离开循环
continue:跳过循环,即跳过这一轮循环,进行下一轮循环
2.多重循环
1.嵌套的循环:在循环里面还是循环
2.从嵌套的循环中跳出:break只能跳出其所在的循环
跳出多重循环可以采用 接力break,设置exit变量
3.循环应用
1.前n项求和
1-1/2+1/3-1/4+…+1/n
找规律,可以先设置sign=1,然后每次循环都改变sign的正负号
2.求最大公约数
可以用辗转相除法
3.整数分解
六、数组与函数
1.数组
1.初试数组
2.定义数组
类型 数组名[元素数量];
int grades[100];double weight[20];
数组是一种容器,用来存放东西,特点是:其中所有的元素具有相同的数据类型;一旦创建,不能改变大小;
数组越界,指针问题有点儿玄学,所以一定要规范
数组下标从0开始,是为了方便制作C的编译器,而后随着C语言的影响扩散开来。
长度为0的数组可以存在,但是无用。
3.用数组做散列计算
2.函数的定义与使用
1.初见函数
代码复制是程序质量不良的表现。因为将来如果需要维护修改复制的代码,就可能要维护很多处。把重复部分作出一个函数来,就可以在各种地方使用它。
2.函数的定义和使用
3.从函数中返回
return:
一个函数可以出现多个return,但尽量只在最后用一个,因为不符合单一出口准则。
3.函数的参数和变量
1.函数原型
函数头加上分号就是函数原型
养成习惯把自定义函数写在上面,因为C的编译器是自上而下分析你的代码
2.参数传递
3.本地变量/局部变量
生存期、作用域:
- 生存期:什么时候这个变量开始出现了,到什么时候它消亡了
- 作用域:在(代码的)什么范围内可以访问这个变量(这个变量可以起作用)
- 对于本地变量,这两个问题的答案是统一的:大括号内——块
4.杂事
4.二维数组
二维数组初始化
七、数组运算
1.数组运算
1.数组运算
数组初始化为0可以直接 int a[]={0};
数组大小=sizeof(a)/sizeof(a[0]);
sizeof 是一个运算符,给出某个类型或变量在内存中所占据的字节数,如sizeof(int)、sizeof(i)
在初始化数组的最后一个元素后面加一个逗号,不会影响编译,但方便后来人添加数据,这是一种古老的,口耳相传的传统,有没有逗号体现出你有没有读过七八十年代的计算机书,可以用它装一装…
数组之间不能直接赋值,必须遍历。
数组作为函数参数时,必须再用另一个参数来传入数组大小
2.数组例子:素数
判断一个数x是否为素数的方法:
- 从2到x-1测试是否有整除
- 去掉偶数,从3到x-1,每次+2
- 无需到x-1,到sqrt(x)就够了
- 判断能否被已知的且<x的素数整除
不断向数组写入数据:prime[count++]=i;
2.搜索
1.线性搜索
一专多能是不好的代码
2.搜索的例子
3.二分搜索
需要是有序数组,时间复杂度为log2(n)
3.排序初步
选择排序
八、指针与字符串
1.指针
1.取地址运算:&运算符取得变量的地址
& 不能对没有地址的东西取地址,如 a+b、a++、++a 等。
2.指针:指针变量就是记录地址的变量
学计算机,一定要有一个非常强大的心理状态,计算机的所有东西,都是人做出来的,别人能想得出来的,我也一定能想得出来,在计算机里头,没有任何黑魔法,所有的东西,只不过是我现在不知道而已,总有一天,我会把所有的细节所有的内部的东西全都搞明白。
把地址交给一个整数是不靠谱的,因为整数和地址不见得永远是相同的类型,指针变量就是保存地址的变量。
int* p,q;和int *p,q;一样,都是定义了一个指针 *p和一个整数q
3.指针与数组:为什么数组传进函数后的sizeof不对了
2.字符类型
1.字符类型
字符型(char)用于储存字符(character),如英文字母或标点。严格来说,char 其实也是整数类型(integer type),因为 char 类型储存的实际上是整数,而不是字符。计算机使用特定的整数编码来表示特定的字符。美国普遍使用的编码是 ASCII。
char是一种整数,也是一种特殊的类型:字符。字符面量用单引号表示,如:‘a’,‘1’。‘’也是一个字符。scanf和printf里面用%c来输入输出字符。一个字符加一个数字得到ASCII码表中那个数之后的一个字符。
2.逃逸字符
黑窗 shell
3.字符串
1.字符串
人眼的横向距离是有限的,16:9看电影很舒服,看代码更适合转过来,所以代码不宜写太长,但应注意,Tab键缩进也会读成空格:
C语言出现在1970年代的早期,在80年代开始,计算机才更多地投入做信息处理,信息处理和数值处理的最大不同就在于处理对象。在C语言的年代更多地要处理数字,而80年代以后,计算机更多地处理文字,所以新的语言会更关心处理文字的能力。