目录
2020年8月27日,今天是来华清的第一个周六,就目前一周的学习来说,感觉还好。第一周学的东西不多但很细,借此文章,以这种碎碎念的方式回顾重点、重复盲点、加深印象,复习、总结和反思本周的学习,仅供后期自己回顾使用。
第一天 周二
1.1 Linux系统的使用
主要是讲的Linux系统的使用,因为大学期间接触过,而且华清也曾在大学里给我们实训过,所以这一步没有太多的问题,刚开始接触感觉要先理解Linux系统文件结构,理解这个去掉图形界面的“我的电脑”。用老师画的这个图就比较容易理解:
1.2 终端
再就是对终端的一些基本操作:
shell终端的打开 1、鼠标双击
2、CTRL + alt + t
shell终端的关闭 1、用鼠标点击关闭图标
2、终端输入 exit
字体缩放: 放大:CTRL + shift + 加号键
缩小: CTRL + 减号复制和粘贴:
复制:ctrl shift c
粘贴:ctrl shift v
切换输入法 ctrl + 空格
切换中英文 shift
1.3 Linux系统命令
除此之外,比较基础的就是系统命令了,太多太杂,简单记一下,我感觉用的多了,问题也不大;简单汇总一下常用、易错的Linux的命令,加深一下印象:
查看当前路径下的 目录或文件 ls
创建文件夹 mkdir 空格 文件夹名字
删除文件夹 rm 空格 -r 空格 要被删除的文件夹名字
创建文件 touch 空格 文件名
删除文件 rm 空格 要被删除的文件名字
切换路径 cd 空格 要切换到的路径名
. -->代表当前路径
../-->代表上一级路径
复制文件 cp 空格 要被复制的文件名 空格 要被复制到的目标路径
复制文件夹 cp -r 空格 要被复制的文件夹名 空格 要被复制到的目标路径
数据重定向 echo 空格 要写入文件的数据 空格 > 空格 要写入数据的文件
打印文件中的数据 cat 空格 要被打印的文件名
移动(剪切)文件 mv 空格 要被移动的文件 空格 要被移动到的目标路径
文件重命名 mv 空格 要被改名的文件 空格 要改成的文件名
1.4 vi编辑器的使用
最后的重头戏是vi编辑器的使用,作为最常用的的编辑器,需要学习和注意的地方有很多,写几个当时自己踩得坑:
ctrl + 空格 切换输入法
shift 切换中英文
(在中文输入法的模式下,是用不了的命令行模式和底行模式的)
其他的就是一些快捷操作了,还是需要多用,方便记忆:
命令行操作:
yy 复制光标所在的行
nyy 从光标所在行开始 复制n行 n是一个数字
p 从光标所在行下面开始粘贴
P 从光标所在行上面开始粘贴
dd 剪切光标所在的行
ndd 从光标所在行开始 剪切n行 n是一个数字
gg 将光标定位到文件开头
G 将光标定位到文件结尾
ngg 将光标定位到第n行
u 撤销上一步的操作
ctrl + r 重做上一次撤销的操作
/word 在文件中查找单词 word 按回车后 n 查找一个 N 查找上一个
底行模式:
:wq 保存并退出 使用 :x 也可以
:w 保存
:q 退出
:q! 不保存强制退出
:vsp 文件名 左右分屏打开多个文件进行编辑
:wqa 保存并关闭所有已经打开的文件
:noh 取消查找结果的高亮显示
:set number 显示行号 或者 :set nu 也可以
:set nonumber 取消显示行号 或者 :set nonu 也可以
:%s/aaa/bbb/g 将全文中所有的aaa替换成bbb
:m,ns/aaa/bbb/g 将m到n行的所有aaa替换成bbb m和n是数字
:%s/aaa/bbb/gc 将全文中所有的aaa替换成bbb 会询问每个单词是否替换 y替换 n 不替换
第二天 周三
2.1 顺利进入(“hello world”)阶段。
#include <stdio.h>
int main(int argc, const char *argv[])
{
printf("hello world\n");//一切苦痛的开始(bushi
return 0;
}
2.2 gcc编译器
编程语言分为编译型语言(C、C++)和解释型语言(shell、python),接下来是讲的gcc编译器,分步编译流程分为:预处理-->编译-->汇编-->链接。、
预处理: 头文件的展开、注释的删除、宏定义的替换
gcc -E xxx.c -o xxx.i
编译: 词法分析、语法分析 用来查错的
如果无误,会生成汇编文件
gcc -S xxx.i -o xxx.s
汇编: 将汇编文件生成二进制文件
gcc -c xxx.s -o xxx.o
链接: 链接库文件 生成最终的可执行文件
gcc xxx.o -o a.out
2.3 进制规则
再就是十进制、二进制、八进制和十六进制的相关问题,这个很重要的,但也很容易理解,这里就不赘述了。附一个老师补充的终端输出各进制的程序,之前没接触过,加深印象:
#include <stdio.h>
int main(){
//int 是数据类型 是用来定义变量用的
//a 是自己定义的变量明 变量是用来存储数据的
int a = 100;//存储十进制的100
printf("a = %d\n", a);//%d 是十进制的占位符 标识按十进制输出 a 的值
printf("a = %#o\n", a);//%o 是八进制的占位符 #表示输出前导符
printf("a = %#x\n", a);//%x 是十六进制的占位符 #表示输出前导符
//C语言的printf函数没有输出二进制的功能
// 等后面我们学了为运算 指针等知识 可以自己写一个能输出二进制的代码
int b = 0b10101100;//存储二进制数据
printf("b = %d , b = %#o , b = %#x\n", b, b, b);
int c = 0456;//存储八进制数据
printf("c = %d , c = %#o , c = %#x\n", c, c, c);
int d = 0xAB34;//存储十六进制数据
printf("d = %d , d = %#o , d = %#x\n", d, d, d);
return 0;
}
2.4 ASCII码
常见常用的ASCII码值:
'0' - '9' 48-57
'A' - 'Z' 65-90
'a' - 'z' 97-122
'\0' 0
'\n' 10
注意:单个个字符一般都是用一个单引号引起来的,单引号中只允许出现一个字符
2.5 数据类型
接下来是小重点:数据类型,C语言的本质是操作内存,内存分配的最小单位是字节,1字节等于8bit,数据类型的作用相当于模子,他为由他定义的变量开辟对应的内存空间。
char 字符类型:
占用空间的大小:1字节 8bit;
能存储的数据范围:
无符号:[0 , 2^8-1]
有符号:[-2^7 , 2^7-1]
short 短整型
占用空间的大小:2字节 16bit
能存储的数据范围:
无符号:[0 , 2^16-1]
有符号:[-2^15 , 2^15-1]
int 整型
占用空间的大小:4字节 32bit
能存储的数据范围:
无符号:[0 , 2^32-1]
有符号:[-2^31 , 2^31-1]
long 长整型
在32位系统中 和 int 一样
在64位系统中 和 long long 一样
long long 长长整型
也可以写成 long long int
占用空间的大小:8字节 64bit
能存储的数据范围:
无符号:[0 , 2^64-1]
有符号:[-2^63 , 2^63-1]
原码、反码、补码转换的问题
数据在存储到计算机的过程中,涉及到原码、反码、补码转换的问题
原码--是给人类看的
反码--是用来做原码和补码转换的
补码--是给计算机看的
无符号数:原码、反码、补码 是一样的
有符号正数:原码、反码、补码 是一样的
有符号负数:
反码 = 原码中符号位不变,数据位按位取反(1变成0 0 变成 1)
补码 = 反码+1
第三天 周四
3.1 变量
变量是在整个程序运行的过程中,值允许发生变化的量,作用是分配特定空间,等待存储数据。
3.2 强制类型转换
包括显示强转和隐式强转。
注意:强制类型转换是不安全的,要谨慎使用:小的类型转大的一般没问题,但是大的类型转小的就可能出现数据的截断。
3.3 运算符
根据类型区分:
算数运算符:+ - * / %(模除 取余运算 模除运算符要求左右操作数必须是整型) ++ --
关系运算符:> < >=
逻辑运算符:&& || !
位运算符: & | ^ ~ >
赋值运算符:= += -= *= /= %= &= |= (复合赋值运算符)
条件运算符: ?: (C语言中唯一一个三目运算符)
sizeof运算符:计算变量或者类型的大小的
逗号运算符:不常用
特别注意自增自减运算符:
以++运算符为例 不管是 a++ 还是 ++a ,执行之后 a 的值都会 +1
但是表达式的结果是不一样的
a = 10;
b = ++a;
上述两步之后 a = 11 b = 11
a = 10;
b = a++;
上述两步之后 a = 11 b = 10
关系运算符:
注意:一定要区分 = 和 ==
= 赋值运算符
== 关系运算符
逻辑运算符:
逻辑运算符的短路原则:
逻辑与连接的多个表达式,如果遇到某一个为假了,后面的表达式就不再执行了
逻辑或连接的多个表达式,如果遇到某一个为真了,后面的表达式就不再执行了
位运算符:
& 按位与:按位运算,全1为1,有0为0
| 按位或:按位运算,有1为1,全0为0
^ 按位异或:按位运算,不同为1,相同为0
~ 按位取反:1变0 0变0
>> 按位右移:整个数据向右移动,舍弃低位,高位补0
小技巧:
0与任何数 结果都是0
0或任何数 结果都是任何数
1或任何数 结果都是1
1与任何数 结果都是任何数
运算符优先级问题:
单算移关与,异或逻条赋。
3.4 三种办法实现两数交换
方式1:三杯水交换 --最常用的方式
int temp = 0;
temp = a;
a = b;
b = temp;
方式2:通过加减的方式 --这种方式是有风险的,数据大的时候会导致数据溢出
a = a + b; //30 20
b = a - b; //30 10
a = a - b; //20 10
方式3:三次异或实现两数交换
a = a ^ b;
b = a ^ b;
a = a ^ b;
第四天 周五
4.1 putchar/getchar
putchar:输出字符
可以传:字符常量:‘H’、字符对应的ascii码值:65、存值的变量(字符的ascii码值)、表达式(a+2)。
getchar:获取字符
在终端获取一个字符,连续获取时会产生垃圾字符(\n),可以在在两个getchar之间加一个getchar吃掉垃圾字符(\n)。
4.2 puts/gets
puts:输出字符串
可以传:字符串常量、保存字符串的数组、指向字符串的指针;
注意:c语言处理字符串的时候,遇到\0就会结束。
gets:获取字符串
允许输入带有空格的字符串;
注意:运行时会报警告,需要保证定义的字符串数组足够大。
4.3 printf/scanf
printf:
向终端输出一个字符串(可以是自己格式化的);
scanf:
在终端获取数据;
scanf垃圾字符的处理:
#include <stdio.h> int main(int argc, const char *argv[]) { char v1, v2, v3; /* //场景1 多个scanf获取字符 连续调用的时候 scanf("%c", &v1); getchar();//吃掉垃圾字符 \n scanf("%c", &v2); getchar(); scanf("%c", &v3); getchar(); */ //场景2:在一个scanf中多次获取 字符时 //scanf("%c%c%c", &v1, &v2, &v3); //处理方式1 使用抑制符来处理 * //抑制符的作用是获取一个数据但是不赋值给后面的变量 //注意 抑制符 无论如何都是要吃掉一个字符 //scanf("%c%*c%c%*c%c", &v1, &v2, &v3); //方式2:使用 空格 来处理 空格会吃掉所有的垃圾字符 --常用的方式 //这种方式就没法获取空格或者回车了 scanf("%c %c %c", &v1, &v2, &v3); printf("v1 = [%d] [%c]\n", v1, v1); printf("v2 = [%d] [%c]\n", v2, v2); printf("v3 = [%d] [%c]\n", v3, v3); return 0;
4.5 if..else语句
if else语句的注意事项:
1.如果if..else语句的代码块只有一行,那么{}可以不用写
2.else 之前必须要有if与之对应 都这会报错
3.else 与同一层次的前面与之最近的 if 结合
4.if..else语句的表达式一般情况下是个由关系运算符和逻辑运算符组成的
如果是异常情况,需要注意下面的写法
if(a=b) //这种写法 表达式的结果取决于b的值,b为0 则为假 b为非0 则为真
if(a=10) //这种写法条件恒为真 所以一般常量和变量比较相等时
//建议将常量写在左边 这样写,少写等号的时候 编译器会报错
if(a) //表达式的结果取决于a的值 a为0 则为假 a为非0 则为真
//等价与 if(a!=0)
if(!a) //表达式的结果取决于a的值 a为0 则为真 a为非0 则为假
//等价于 if(a == 0)
5.在同一层次中同时出现两个 if 时
if(){}
if(){}
//这两个if是独立的 相互之间不影响
周末练习
6.1 练习1
从键盘输入一个正整数,求这个数的阶乘
//练习1
//从键盘输入一个正整数,求这个数的阶乘
#include <stdio.h>
int main(int argc, const char *argv[])
{
int get_num;
int i;
int res=1;
printf("请输入一个正整数:");
scanf("%d",&get_num);
for(i=1;i<=get_num;i++){
res=res*i;
}
printf("%d的阶乘是%d\n",get_num,res);
return 0;
}
6.2 练习2
求自然数之和
//求自然数之和
#include <stdio.h>
int main(int argc, const char *argv[])
{
int get_num;
int i;
int res = 0;
printf("请输入一个正整数:");
scanf("%d",&get_num);
for(i=1;i<=get_num;i++){
res+=i;
}
printf("%d的自然数之和是:%d\n",get_num,res);
return 0;
}
6.3 练习3
求0到100之间的质数
//求0到100之间所有的指数
#include <stdio.h>
int main()
{
int i;
int j;
printf("质数有:\n");
for(i=2;i<100;i++){
for(j=2;j<i;j++){
if(i%j==0)
break;
}
if(j==i)
printf("%d ",i);
}
printf("\n");
return 0;
}
6.4 练习4
求[100,1000)中的水仙花数:
(水仙花数:一个数的各个位的平方之和等于这个数;)
//水仙花数
#include <stdio.h>
int main()
{
int a=100;
int g,s,b;
int sum;
printf("[100,1000)中的水仙花数有:");
for (a;a<1000;a++){
g=a%10;
s=a/10%10;
b=a/100;
sum=g*g*g+s*s*s+b*b*b;
if (sum==a){
printf("%d ",a);
}
}
printf("\n");
return 0;
}
6.5 练习5
求[2,1000)中的完数:
(完数:一个数因子的和等于自身;)
#include <stdio.h>
int main()
{
int i,j;
int sum;
printf("[2,1000)中的完数有:\n");
for(i=2;i<1000;i++){
sum=0;
for(j=1;j<i;j++){
if(i%j==0)
sum+=j;
}
if(i==sum)
printf("%d ",i);
}
printf("\n");
return 0;
}
6.6 练习6
输出指定数量的斐波那契数列
//输出指定数量的斐波那契数列
//
#include <stdio.h>
int main(int argc, const char *argv[])
{
int i;
int sum = 0;
int t1 = 0;
int t2 = 1;
int get_num;
printf("请指定一个正整数:");
scanf("%d",&get_num);
printf("%d个斐波那契数列为:\n",get_num);
for(i=1;i<=get_num;i++){
printf("%d\t",t2);
sum = t1+t2;
t1 = t2;
t2 = sum;
}
printf("\n");
return 0;
}
6.7 练习7
打印九九乘法表
#include <stdio.h>
int main()
{
int a,b,c;
for(a=1;a<=9;a++){
for(b=1;b<=a;b++){
c=a*b;
printf("%d X %d = %d ",a,b,c);
}
printf("\n");
}
return 0;
}
总结与反思
第一个周,老师为了匹配每个人的进度,讲的不是很快,讲的也很细,对于这些前期比较基础的知识,自己还是能应付的过来;对于接下来的更深入的学习来说,感觉还是需要更努力才行;并且发现自己在逻辑方面有很多问题,具体问题具体分析的时候脑子容易转不过来,思维方式还需要尽快培养,还需多练多写。
写在最后:写这篇文章是笔者一边看老师的目录,一边回想老师讲的内容,仅仅选取了我自己认为比较重要的,或者自己之前没接触过的进行汇总、总结,知识体系不完善,内容也不详细,仅供笔者复习使用。如果是有需要笔记,或者对这方面感兴趣,可以私信我,发你完整的知识体系和详细内容的笔记。写的仓促、水平有限,如有任何错误请多指正,也欢迎友好交流,定会虚心听取大佬的宝贵意见!