大学C语言程序设计
chapter 1 顺序结构
1. 编程的概念
程序:为实现特定目标或解决特定问题而用计算机语言编写的一系列指令序列。
计算机语言:人与计算机之间通信的语言。计算机语言有很多种,比如BASIC语言、PASCAL语言、C语言、C++语言、Java语言等,每种计算机语言都有自身定义的规则,即使是同一种语言也有不同的版本,内部规则也会有少许不同。
编程:可以简单的理解为程序员为了解决特定问题,按照自己的思路,在遵循特定的计算机语言规则下编写程序的过程。
面向过程:以解决问题本身作为解决目标。
面向对象:以问题根源作为解决目标。
2. 编程软件
工欲善其事,必先利其器,一个好的编译软件可以使我们的学习事半功倍
现在对于初学者常用的编译软件很多, 如:VC6.0,CodeBlocks,Dev-C++
本次课程使用Dev-C++软件,主要是使用方便,小巧,对于如何下载和安装,请查看以下链接,点击可跳转:
3. 键盘和鼠标的使用
鼠标的介绍
鼠标分为:左右键,滚轮
左键用于选择和确认,一般可单击(表示选择),双击(表示确认)
右键用于项目提示和调出选项选择框,一般将其放在我们要操作的项目上,右键单击,就会出现一个新的小框,供我们选择,这时候选择应当使用:左键
滚轮用于上下翻页(部分可以左右翻页),如果和 Ctrl 结合使用,会出现大小缩放的效果,即放大缩小。
键盘快捷键
作用 | 快捷键 | 作用 | 快捷键 | 作用 | 快捷键 |
---|---|---|---|---|---|
缩放 | Ctrl+滚动滚轮 | 缩小 | Ctrl + '-'(键盘按键) | 放大 | Ctrl + '+'(键盘按键) |
中英文切换 | Ctrl + 空格 | 输入法切换 | Ctrl + shift | 大小写切换 | CapsLock |
全选 | Ctrl + A | 复制 | Ctrl + C | 粘贴 | Ctrl + V |
删除 | Delete / Backspace | 剪切 | Ctrl + X | 查找 | Ctrl + F |
新建 | Ctrl + N | 保存 | Ctrl + S | 回退 | Ctrl + Z |
如果我们要使用:#, %, /, "",+,(), * 等键盘上的复合型按键怎么调出来呢?
需要先按住 Shift ,再按对应的按键(记住:此时 Shift不能松开, 上述快捷键 Ctrl 也是一样)
如果程序编辑页面的定位符变成了一个黑色小方块,那么按一下键盘上的:Insert
注意:书写程序时,全部的代码都是在英文状态下编写的,也就是输入法的状态为 English
4. 注释
注释是指在程序中,写给我们开发者自己看的内容,这部分内容不被编译器编译运行。即使我们不写或者删除都不会对程序产生影响。
也就是说编译器在编译代码时,会忽略注释的内容
注释通常放在一行代码的上方,或者一条语句的末尾。
// 注释内容
:单行注释符,用于单独一行的注释;/* 注释内容 */
:多行注释符,用于对多行进行注释,也称 块注释。/注释内容/中的注释内容可以为中文,外文,乱码等任意符号,且可以换行,即使你突然灵感爆发,在这里写上一个千字文章也未尝不可。
在devC++编译器中注释的快捷键为:Ctrl +/
5. 常用的数据类型
数据类型 | 类型标识符 | 存储大小 | 数据范围 |
---|---|---|---|
字符型 | char | 1B | [-2^7, 2^7-1] |
短整型 | short | 2B | [-2^15, 2^15-1] |
整型 | int | 4B | [-2^31, 2^31-1] |
单精度浮点数 | float | 4B | [-2^128, 2^128] |
双精度浮点数 | double | 8B | [-2^1024, 2^1024] |
长整型 | long | Win(4B),Linux_32(4B),Linux_64(8B) | [-2^31, 2^31-1] |
长长整型 | long long | 8B | [-2^63, 2^63-1] |
无符号整型 | unsigned int | 4B | [0, 2^32-1 ] |
无符号长整型 | unsigned long | 4B | [0, 2^32-1] |
无符号长长整型 | unsigned long long | 8B | [0, 2^64-1] |
补充知识: sizeof 关键字
作用:利用sizeof关键字可以统计数据类型所占内存大小
语法:sizeof(数据类型或变量)
6. 变量名
变量:类似于我们数学上所学习的 x、y
作用:给一段指定的内存空间起名,方便操作这段内存
语法:数据类型 变量名 = 初始值;
变量名:在计算机语言中变量表示某个存储数据空间的名称。
它的命名有如下规则:
(1)变量名中只能出现字母(A~Z,a~z)、数字(0~9)或者下划线。
(2)第一个字符不能是数字。
(3)不能是C++关键字。所谓关键字,即C++中已经定义好的有特殊 含义的单词。
(4)区分大小写。
变量名补充:
(1)对变量名(也就是标识符)的长度没有统一规定,随着系统的不同而有不同的规定,一般来说,C++编译器可以识别前31个字符,所以标识符的长度不要超过31位。
(2)给标识符命名时,争取做到见名知意的效果,方便自己和他人的阅读。
关键字
关键字(keyword)又称保留字,是整个语言范围内预先保留的标识符。
每个C++关键字都有特殊的含义。经过预处理后,关键字从预处理记号(preprocessing-token)中区别出来,剩下的标识符作为记号(token),用于声明对象、函数、类型、命名空间等。不能声明与关键字同名的标识符(变量,函数等)。
补充: C++关键字如下
作用类型 | 关键字 |
---|---|
数据类型 | void,int,char,float,double,bool,w_char |
类型定义 | struct,union,enum,class,typedef |
常量值 | true,false |
类型修饰符 | long,short,singed,unsigned |
类型限定符 | const,volatile,restrict |
存储说明符 | auto,register,static,extern,thread_local,mutable |
其它修饰符 | inline,asm |
循环控制 | for,while,do |
跳转控制 | break,continue,return,goto |
分支结构 | if,else,switch,case,default |
内存管理 | new, delete |
运算符 | sizeof,and,and_eq,bitand,bitor,compl,not,not_eq,or,or_eq,xor,xor_eq |
访问限定符 | this,friend,virtual,mutable,explicit,operator |
类访问修饰符 | private,protected,public |
模板 | template,typename |
命名空间 | namespace,using |
异常处理 | throw,try,catch |
7. 运算符
算术运算符
符号 | 作用 | 使用 | 备注 |
---|---|---|---|
+ | 加 | 1+2=3 | |
- | 减 | 1-2=-1 | |
* | 乘 | 1*2=2 | |
/ | 除 | 1/2=0 1.0/2=0.5 |
如果/两边都为整数,则结果取整; 如果有一个是浮点数,则结果为浮点数 |
% | 模,取余数 | 1%2=1 | %符号两边必为整数 |
++ | 加1 | a++; ++a; |
a++:先使用再加 ++a :先加再使用 |
-- | 减1 | a--; --a; |
a--:先使用再减 --a:先减再使用 |
赋值运算符
符号 | 使用 | 作用 |
---|---|---|
+= | a += 2; | 等同于 a = a + 2; |
-= | a -= 2; | 等同于 a = a - 2; |
*= | a *= 2; | 等同于 a = a * 2; |
/= | a /= 2; | 等同于 a = a / 2; |
%= | a %= 2; | 等同于 a = a % 2; |
算数运算符的4个注意
- a / b,若 a,b均为整数,则结果为整数,若其中一个为浮点数,则结果为浮点数;
- a % b ,要求:a, b均为整数;
- 遵循算数的自然特征,如分母不为0;
- 防止数据长度溢出。
补充:赋值运算符
-
由于赋值运算符
=
右边的表达式也可以是赋值表达式,因此,下述形式 :变量=(变量=表达式);
是成立的,从而形成嵌套的情形。其展开之后的一般形式为:变量=变量=…=表达式;
例如a=b=c=d=e=5;
,它实际上等价于:e=5;d=e;c=d;b=c;a=b;
-
在进行赋值运算时,如果赋值运算符两边的数据类型不同,系统将会自动进行类型转换,即将赋值运算符右边的数据类型转换成左边的变量类型。当左边是整型而右边是实型时,将去掉小数部分并截取该整型对应的有效位数。
8. 数学表达式
函数名 | 格式 | 功能 | 举例 |
---|---|---|---|
向下取整 | floor(x) | 不大于x的最大整数 | floor(3.14)=3 |
向上取整 | ceil(x) | 不小于x的最小整数 | ceil(3.14)=4 |
指数函数 | pow(x,y) | 计算y个x的乘积 | pow(3,2)=3*3=9 |
平方根函数 | sqrt(x) | 求x的平方根 | sqrt(9)=3 |
绝对值函数 | abs(x) | 求x的绝对值 | abs(-3)=3 |
随机值函数 | rand() | 随机生成一个0~pow(2,16)-1的整数 | rand()=41 |
自然数指数函数 | exp(x) | 求实数x的自然指数ex | exp(1)=2.718282 |
自然对数函数 | log(x) | 求实数x的自然数对数 | log(1)=0 |
使用前需导入头文件:#include<math.h>
9. 常量
常量的作用:用于记录程序中不可更改的数据
常量的书写:大写
常量的特性:只读不可写
两种定义常量的方式
方式一: const int X = 2;
定义的常量X=2,且不能修改,否则报错
如以下程序就会报错:
const int X = 2;
X = 3; //error
一般我们将常量定义在外面,但是也可以定义在main中。
方式二:#define 常量名 常量值
宏定义,通常在文件上方定义,表示一个常量
如:#define PI 3.14
,相当于PI = 3.14,以后就可以直接使用 PI。
10. 运算符补充
类型 | 作用 |
---|---|
1.算术运算符 | 用于各类数值运算。包括加(+)、减(-)、乘(*)、除(/)、求余(或称模运算,%)、自增(++)、自减(--)共七种。 |
2.关系运算符 | 用于比较运算。包括大于(>)、小于(<)、等于(==)、大于等于(>=)、小于等于(<=)和不等于(!=)六种。 |
3.逻辑运算符 | 用于逻辑运算。包括与(&&)、或(||)、非(!)三种。 |
4.位操作运算符 | 参与运算的量,按二进制位进行运算。包括位与(&)、位或(|)、位非(~)、位异或(^)、左移(<<)、右移(>>)六种。 |
5.赋值运算符 | 用于赋值运算,分为简单赋值(=)、复合算术赋值(+=,-=,*=,/=,%=)和复合位运算赋值(&=,|=,^=,>>=,<<=)三类共十一种。 |
6.条件运算符 | 这是一个三目运算符,用于条件求值(?:)。 |
7.逗号运算符 | 用于把若干表达式组合成一个表达式(,)。 |
8.指针运算符 | 用于取内容(*)和取地址(&)二种运算。 |
9.求字节数运算符 | 用于计算数据类型所占的字节数(sizeof)。 |
10.特殊运算符 | 有括号(),下标[],成员(->,.)等几种。 |
说明:大体的运算顺序是:先乘除,再加减,后赋值
或者:! > 算术运算符 > 关系运算符 > && > || > 赋值运算符
如果真的记不住,那么可以通过()来改变运算优先顺序,()内先运算。
优先级 | 运算符 | 名称或含义 | 使用形式 | 结合方向 | 说明 |
---|---|---|---|---|---|
1 | [ ] | 数组下标 | a[100] | 左到右 | |
( ) | 圆括号 | a*(b+c) | |||
. | 成员选择(对象) | a.b | |||
-> | 成员选择(指针) | a->b | |||
2 | +, - | 正运算符,负运算符 | +a,-a | 右到左 | 单目运算符 |
! | 逻辑非运算符 | ||||
~ | 按位取反运算符 | ||||
++,-- | 自增运算符,自减运算符 | ++a, a++,--a, a-- | |||
*,& | 取值运算符,取址运算符 | *a,&a | |||
(type) | 强制类型转换 | (int)a | |||
sizeof | 长度运算符 | sizeof(float) | |||
3 | *,/,% | 乘,除,取余 | a%b | 左到右 | 双目运算符 |
4 | +,- | 加,减 | a+b | ||
5 | << ,>> | 左移, 右移 | a>>1, b<<c | ||
6 | >, >= | 大于, 大于等于 | a > b, a >= b | ||
<, <= | 小于, 小于等于 | a < b, a <= b | |||
7 | ==, != | 等于,不等于 | a == b, a != b | ||
8 | & | 按位与 | a&b | ||
9 | ^ | 按位异或 | a^b | ||
10 | | | 按位或 | a|b | ||
11 | && | 逻辑与 | a&&b | ||
12 | || | 逻辑或 | a||b | ||
13 | ? : | 条件运算符 | a?b:c | 右到左 | 三目运算符 |
14 | = | 赋值 | |||
*=, /=, %= | 乘(除/取余)后赋值 | ||||
+=, -= | 加(减)后赋值 | ||||
<<=, >>= | 左(右)移后赋值 | ||||
&=, |=, ^= | 按位与(或/异或)后赋值 | ||||
15 | , | 逗号运算符 | int a, b; | 左到右 |
11. 类型转换
- 自动类型转换
- 强制类型转换
- 字符型和整型的转换
1.自动类型转换
在不同数据类型的混合运算中,编译器会隐式地进行数据类型转换,称为自动类型转换。
自动类型转换遵守以下规则:
(1)若参与运算的数据类型不同,则先转换成同一类型,然后进行运算。
(2)转换按数据长度增加的方向进行,以保证精度不降低。例如int类型和long long类型运算时,先把int转换为long long后再运算。
(3)在赋值运算中,赋值号两边的数据类型不一样时,将把右面表达式的类型转换为左边变量的类型。如果右边表达式的数据类型长度比左边的长时,将丢失一部分数据。
即:char -->short -->int --> float -->double
2.强制类型转换
当自动类型转换不能实现目的时,可以显示的进行类型转换,称为强制类型转换。
强制类型转换的一般形式是: (类型名)(表达式) (类型名)变量
如(double)a 是将a转换为double型,
(int)(x + y) 是将 x+y 的值转换为整型,
(float)5/3 是将 5 的值转换成float型,再与 3 运算。
double为双精度浮点型,float为单精度浮点型,区别在于他们的精度不同。
3.字符型和整型的转换
将一个字符放到内存单元时,实际上并不是把该字符本身放到内存中,而是将该字符的ASCII代码放到存储单元中。
如字符变量c1的值是'a',c2的值是'b',则在变量中存放的是 'a' 的ASCII码97,'b' 的ASCII码98
12. C语言输入输出
基本输入输出格式 | 输入 | 输出 |
---|---|---|
符号 | scanf | printf |
int类型的输入输出 | scanf("%d",&a); | printf("%d",a); |
float类型的输入输出 | scanf("%f %f",&a, &b); | printf("%f %f",a, b); |
double类型的输入输出 | scanf("%lf",&a); | printf("%lf",a); |
注意:使用前需要导入头文件#include<cstdio>
#include<cstdio>
int main(){
int a;
scanf("%d", &a); //输入并赋值给a,注意输入有符号&,输出没有
printf("a = %d\n", a); //输出a的值,并换行
float b;
scanf("%f", &b);
printf("b = %f\n", b); //输出b,默认保留小数后6位
printf("b = %.4f\n", b);//输出b,保留小数后4位
double c;
scanf("%lf", &c);
printf("c = %6.4lf\n", c);//输出c,宽度为6,保留小数后4位
long long d;
scanf("%ld", &d);
printf("d = %ld\n", d);//输出d
//也可以一起使用
printf("a = %d b = %f c = %lf d = %lld\n",a,b,c,d);
printf("a = %d b = %2.3f c = %3.4lf d = %lld\n",a,b,c,d);
return 0;
}
函数名:scanf
功 能:执行格式化输入
用 法:int scanf(char *format[,argument,...]);
scanf()函数是通用终端格式化输入函数,它从标准输入设备(键盘) 读取输入的信息。
可以读入任何固有类型的数据并自动把数值变换成适当的机内格式。
其调用格式为: scanf("<格式化字符串>",<地址表>);
scanf()函数返回成功赋值的数据项数,出错时则返回EOF
。
格式表示 | 意义 |
---|---|
%c | 一个(ASCII)字符,一个汉字实际上在内存中要占据两个字符的位置。 |
%s | 一串字符,字符串。 |
%nd %ld | 一个十进制整数,n为输出占位宽度。 printf(“%12d”,a); 如a为数字8,则前面补齐11个空格, ld表示 长整型数据 |
%nx %nX | 一个十六进制整数,n为输出占位宽度。 |
%no | 一个八进制整数,n为输出占位宽度。 |
%n.mf | 单精度浮点数,n代表该浮点数的占位宽度,.m代表小数点后保留几位 a为12.2324,printf(“%.3”,a); 12.232,自动四舍五入。 |
%n.mlf | 双精度浮点数,n代表该浮点数的占位宽度,.m代表小数点后保留几位 a为12.2324,printf(“%.3”,a); 12.232,自动四舍五入。 |
%E | 输出科学计数法,12.12 输出为 1.212000E+001,只适用 float,double。 |
%p | 指针(变量的地址) |
%% | 输出时有用,表示输出一个% |
注意:格式在输入时不能有,在输出时可以有也可以没有
注意:%为变量占位符,\只在printf中使用,为特殊字符的转义字符
流操纵算子 | 作用 |
---|---|
dec | 以十进制形式输出整数 cout << hex << 12 << " " << 24; 则输出:c 18 |
hex | 以十六进制形式输出整数 |
oct | 以八进制形式输出整数 |
fixed | 以普通小数形式输出浮点数 |
scientific | 以科学计数法形式输出浮点数 |
left | 左对齐,即在宽度不足时将填充字符添加到右边 |
right | 右对齐,即在宽度不足时将填充字符添加到左边 |
setbase(b) | 设置输出整数时的进制,b=8、10 或 16 |
setw(w) | 指定输出宽度为 w 个字符,或输人字符串时读入 w 个字符 |
setfill(c) | 在指定输出宽度的情况下,输出的宽度不足时用字符 c 填充(默认情况是用空格填充) |
setprecision(n) | 设置输出浮点数的精度为 n, 在使用非fixed且非scientific 方式输出的情况下,n 即为有效数字最多的位数, 如果有效数字位数超过 n,则小数部分四舍五人,或自动变为科学计数法输出并保留一共 n 位有效数字 在使用 fixed 方式和 scientific 方式输出的情况下,n 是小数点后面应保留的位数 |
setiosflags(标志) | 将某个输出格式标志置为 1,设置输出标志 |
resetiosflags(标志) | 将某个输出格式标志置为 0,清除输出标志 |
13. 转义字符
作用:用于表示一些不能显示出来的ASCII字符
现阶段我们常用的转义字符有: \n \\ \t
转义字符 | 含义 | ASCII码值(十进制) |
---|---|---|
\a | 警报 | 007 |
\b | 退格(BS) ,将当前位置移到前一列 | 008 |
\f | 换页(FF),将当前位置移到下页开头 | 012 |
\n | 换行(LF) ,将当前位置移到下一行开头 | 010 |
\r | 回车(CR) ,将当前位置移到本行开头 | 013 |
\t | 水平制表(HT) (跳到下一个TAB位置) | 009 |
\v | 垂直制表(VT) | 011 |
\\ | 代表一个反斜线字符"\" | 092 |
' | 代表一个单引号(撇号)字符 | 039 |
" | 代表一个双引号字符 | 034 |
? | 代表一个问号 | 063 |
\0 | 数字0 | 000 |
\ddd | 8进制转义字符,d范围0~7 | 3位8进制 |
\xhh | 16进制转义字符,h范围0 ~ 9,a ~ f,A ~ F | 3位16进制 |
14. 实例练习
1.地球人口承载力估计【小学奥数7653】
假设地球上的新生资源按恒定速度增长。照此测算,地球上现有资源加上新生资源可供x亿人生活a年,或供y亿人生活b年。为了能够实现可持续发展,避免资源枯竭,地球最多能够养活多少亿人?
输入:一行,包括四个正整数 x,a,y,b,两个整数之间用单个空格隔开。x>y,a<b,ax<by,各整数均不大于10000
输出:一个实数z,表示地球最多养活z亿人,舍入到小数点后两位。
样例输入: 110 90 90 210
样例输出: 75.00
本题题解
本题目主要找到平衡点,也就是不变量来建立等式
本题目所求的是避免资源枯竭,地球最多能够养活多少亿人,也就是说在现有资源不被消耗的情况下,刚好将新增资源消耗完毕的时候,能养活多少人,也就是要求出新生资源的增长速度。
由于题目中说明新生资源按恒定速度增长,证明新生资源的增长速度是一个定量,那么我们假设该定量为 m.
又地球上现有资源加上新生资源可供x亿人生活a年,或供y亿人生活b年。
首先,现有资源一定是一个定量,新生资源由于ab的变化在发生变化,所以我们可以建立以下等式现有资源 = x*a - m*a;
现有资源 = y*b - m*b;
所以 m = (x*a-y*b)/(a-b);
所以标程(针对本题的解答程序)如下:
#include<cstdio>
int main(){
int x,a,y,b;
scanf("%d %d %d %d",&x, &a, &y, &b);
double z = 1.0*(x*a-y*b)/(a-b);
printf("%.2lf", z);
return 0;
}
2.数学中经典的"鸡兔同笼"问题,已知头共30个,脚共90只,问笼中的鸡和兔各有多少只?
解决方案一:
听我口令,所有动物,提起一只脚
听我口令,所有动物,提起第二只脚
好了,现在着地的还有90-30-30=30只脚
由于鸡只有两只脚,所以这时候的全部鸡都是跪着的,
这30只脚应当都是兔子的,每只兔子有4只脚,提起2只,还剩2只
所以兔子的数量为:30/2=15只
所以鸡的数量为30-15只
解决方案二:
差值求解
假设都为兔,则 缺少 30*4 - 90 = 30支脚
所以这 缺少的脚就是鸡, 所以鸡的数量 = 30/2=15;
兔的数量 = 30-15;
解决方案三:
列方程,设鸡 x只,兔 y只, 则
x + y = 30
2*x + 4*y = 90
解得 x = 15, y = 15
解决方案四:
循环遍历,假设 鸡兔都为0只,每次递增+1,直到满足方案三中方程的xy出现
输出结果
#include<cstdio>
int main(){
int x,y;
x = (30*4-90)/2;
y = 30-x;
printf("%d %d\n", x, y);
}
3.计算并联电阻的阻值
对于阻值为r1和r2的电阻,其并联电阻阻值公式计算如下:R = 1/(1/r1 + 1/r2)。
输入两个电阻阻抗大小,浮点型。输出并联之后的阻抗大小,结果保留小数点后2位。
输入:两个电阻阻抗大小,浮点型,以一个空格分开。
输出:并联之后的阻抗大小,结果保留小数点后2位
样例输入:1 2
样例输出:0.67
#include<cstdio>
int main(){
double r1,r2,R;
scanf("%lf%lf", &r1, &r2);
R = 1/(1/r1+1/r2);
printf("%.2lf\n", R);
}
4.海伦公式
传说古代的叙拉古国王海伦二世发现的公式,利用三角形的三条边长来求取三角形面积。已知△ABC中的三边长分别为a,b,c,求△ABC的面积。(提示:海伦公式)
#include<cstdio>
#include<cmath>
int main(){
double a, b, c, p, s;
scanf("%lf%lf%lf", &a, &b, &c);
p = (a+b+c)/2;
s = sqrt(p*(p-a)*(p-b)*(p-c));
printf("%.2lf\n", s);
}