2.1.1.2 计算机和编程语言:计算机的思维方式
程序的执行
- 解释:借助一个程序,那个程序能试图理解你的程序,然后按照你的要求执行。
- 编译:借助一个程序,就像一个翻译,把你的程序翻译成计算机真正能懂的语言——机器语言——写的程序,然后,这个机器语言写的程序就能直接执行了。
11.2.1.3 变量:变量赋值与初始化
如果变量没有初始化,就直接拿到右边去用,会出现什么呢?
得到了一个非常奇怪的结果,这是因为,在内存当中,我们有一个变量 i 我们没有给它一个初始值,那么,它正好在内存当中,在什么地方,那个地方原本有一些什么样的值在里头,它就是那个值了。
12.2.1.4 变量:变量输入
读整数
scanf("%d", &price);
- 要求scanf这个函数读入下一个整数,读到的结果赋值给变量price。
scanf和printf中,f表示format格式化的意思。
13.2.1.5 变量:常量VS变量
常量(C99)
- int change = 100 - price;
- 固定不变的数,是常数。直接写在程序里,我们称作直接量(literal)。
- 更好的方式,是定义一个常量:
const int AMOUNT = 100
。
#include <stdio.h>
int main()
{
const int AMOUNT = 100;
int price = 0;
printf("请输入金额(元):");
scanf("%d", &price);
int change = AMOUNT - price;
printf("找您%d元。\n", change);
return 0;
}
const(C99)
- const是一个修饰符,加在int的前面,用来给这个变量加上一个const(不变的)的属性。这个const的属性表示这个变量的值一旦初始化,就不能再修改了。
- int change = AMOUNT - price;
- 如果你试图对常量做修改,把它放在赋值运算符的左边,就会被编译器发现,指出为一个错误。
14.2.1.6 变量:浮点数
%lf
对应double。
16.2.2.2 表达式:运算符优先级
注意这里优先级为1的单目运算符+
、-
注意,a=6
这个式子本身,是有结果的,也就是6。
17.2.2.3 表达式:交换变量
视频中4分20秒开始出现Dev C++断点调试的使用方法。
20.3.0.1 编程练习解析:PAT再解释
视频中5分30秒开始,出现了对scanf的讲解。
出现在scanf格式字符串里面的东西,是它一定要你输入的东西,而不是它会给你看的东西。
28.3.2.1 分支:嵌套的if-else
(学习笔记:能用大括号就用大括号,避免歧义。)
29.3.2.2 分支:级联的if-else if
30.3.2.3 分支:if-else的常见错误
31.3.2.4 分支:多路分支
(以下代码利用了switch-case的某个特性)
34.4.1.3 循环:do-while循环
(注意:while结尾要有分号)
35.4.2.1 循环应用:循环计算
(计算之前先保存原始的值,后面可能有用。)
40.5.1.2 第三种循环:循环的计算和选择
41.5.2.1 循环控制:循环控制
(判断素数)
(上面的代码中,设置一个标志位的写法,我认为值得借鉴。)
(判断素数的另一种写法。)
43.5.2.3 循环控制:从嵌套的循环中跳出
#include <stdio.h>
int main()
{
int x;
int one, two, five;
int exit = 0;
scanf("%d", &x);
for (one=1; one<x*10; one++)
{
for (two=1; two<x*10/2; two++)
{
for (five=1; five<x*10/5; five++)
{
if (one + tw0*2 + five*5 == x*10)
{
printf("可以用%d个1角加%d个5角得到%d元\n",
one, two, five, x);
exit = 1;
break;
}
}
if (exit == 1) break;
}
if (exit == 1) break;
}
}
(
我主要对这里的先设置一个标志int exit = 0;
,然后满足某种条件后,改变标志exit = 1
,进而改变程序控制流程的写法,感兴趣。
)
45.5.3.2 循环应用:整数分解
(这一段的视频值得重新一看,整数正序分解,因为C 语言中没有趁手的工具,所以这里实现起来略繁琐。)
46.5.3.3 循环应用:求最大公约数
辗转相除法求最大公约数
48.6.0.2 编程练习解析:编程练习解析4-1
(水仙花数编程实现,值得一看)
49.6.0.3 编程练习解析4-2:九九乘法表
50.6.0.4 编程练习解析4-3:统计素数求和
(关键词:素数、质数)
52.6.0.6 编程练习解析5-0:n项求和
每一项的分子是前一项分子与分母的和,分母是前一项的分子。
(下面的代码值得一看)
54.6.1.1 数据类型:数据类型
sizeof
- 是一个运算符,给出某个类型或变量在内存中所占据的字节数
sizeof(int)
sizeof(i)
55.6.1.2 数据类型:整数类型
整数
- char:1字节(8比特)
- short:2字节
- int:取决于编译器(CPU),通常的意义是“1个字”
- long:取决于编译器(CPU),通常的意义是“1个字”
- long long:8字节
当我们在说1台计算机的字长的时候,我们指的是寄存器是多少宽的,也就是说,这个寄存器是几个bit的。比如说,当我们说寄存器是32个bit的,每一个寄存器可以表达32个bit的数据,同时也是在说,CPU和RAM之间在总线上传递数据的时候,每一次的传递是32个bit,也就是说,当要从内存RAM取数据到CPU里面去,每一次就会要取32个bit。
除了32,现在更常见的是64个bit。
字长在C语言中,反映为int。int表达的是1个寄存器的大小。所以,在不同的平台、CPU上面,int会不一样大。
56.6.1.3 数据类型:整数的内部表达
所以,为什么我们要在计算机的内部使用补码呢?
最大的好处就是,如果你有了一个补码,你用补码来表示这个-1,那么,当你在做加法的时候,你不需要根据条件,去变换,把加+变成减-,你直接拿它去做普通的二进制的加法,你就会得到你想要的那个结果。
57.6.1.4 数据类型:整数的范围
整数越界
整数是以纯二进制方式进行计算的,所以:
- 11111111 + 1 –> 100000000 –> 0
- 01111111 + 1 –> 10000000 –> -128(这里我存在疑问)
- 10000000 + 1 –> 01111111 –> 127
下面的代码似乎可以解答我的疑问:
-2^(32-1) —— 2^(32-1)-1
(关键词:无符号数、unsigned
这整段视频建议重新细看、加强理解。)
58.6.1.5 数据类型:整数的格式化
(如下的代码,建议看视频的详细解释)
59.6.1.6 数据类型:选择整数类型
60.6.1.7 数据类型:浮点类型
(inf:正负的无穷大
nan:表示不是一个有效的数字
这段视频建议再去详细看。)
科学计数法
#include <stdio.h>
int main()
{
double ff = 1234.56789;
printf("%e,%f\n", ff, ff);
return 0;
}
输出:
1234568e+03,1234.567890
#include <stdio.h>
int main()
{
double ff = 1E-10;
printf("%E,%f\n", ff,ff);
return 0;
}
输出:
1.000000E-10,0.000000