进行加法运算时逢 几 进1,进行减法运算时借1当 几
2>二进制、八进制、十六进制转换为十进制 3>十进制转换为二进制、八进制、十六进制整数部分:除 几 取余
小数部分:乘 几 取整
4>二进制和八进制,以及二进制和十六进制之间的转换-
二—>八:三合一,不够0补
-
八—>二:一分三
-
二—>十六:四合一,不够0补
-
十六—>二:一分四
符号位表示:0表示正 、1表示负
-
正数:原反补码都相同
-
负数:反码 = 原码符号位不变,其它位取反
补码 = 反码 + 1
0001 0010 0011 0100 0101 0110 0111 1000 //原码
0000 0000 0000 0000 0000 0111 0000 0000 //0x7<<8
0001 0010 0011 0100 0101 0111 0111 1000 //GPX2CON = GPX2CON | (0x7<<8)
0000 0000 0000 0000 0111 0000 0000 0000 //0x7<<12
1111 1111 1111 1111 1000 1111 1111 1111 //取反:~( 0x7<<12)
0001 0010 0011 0100 0000 0111 0111 1000 //清零:GPX2CON = GPX2CON & ~(0x7<<12)
0000 0000 0000 0000 0110 0000 0000 0000 //0x6<<12
0001 0010 0011 0100 0110 0111 0111 1000 //置位
GPX2CON = GPX2CON & ~(0x7<<12) | 0x6<<12 = 0x12346778
[2] gcc编译流程GCC把源文件生成操作系统可以执行的文件需要经历4个过程
| 后缀名 | 对应的语言 |
|---|---|
| -c | 只编译不链接,生成目标文件".o" |
| -S | 只编译不汇编,生成汇编代码 |
| -E | 只进行预编译,不做其他处理 |
| -g | 在可执行程序种包含标准调试信息 |
| -o file | 把输出文件输出到file里 |
| -v | 打印出编译器内部编译各过程的命令行信息和编译器的版本 |
去掉注释,加载头文件,代替宏定义,条件编译
条件编译 需要文件:.c文件 生成产物:预处理文件(以.i结尾)
gcc -E [源文件] -o [目标文件]
实例:gcc -E hello.c -o hello.i
后缀名为”.i”的文件是经过预处理后的C原始程序。
2> 编译 编译阶段的主要工作是把我们的源代码生成相应的汇编代码的过程。这个阶段花费的时间会比较长。它需要对我们的C语言进行语法和语义的分析。如果有语法错误,报错,并结束编译过程。如果没有语法错误,还需要优化我们的代码,把C的源程序转变为汇编代码。需要文件:.i文件 生成产物:汇编文件(以.s结尾)。
gcc -S [源文件] -o [目标文件]
实例:gcc -S hello.i -o hello.s
后缀名为”.s”的文件是汇编语言原始程序。
3> 汇编 首先我们应该知道汇编代码(汇编指令)并不是机器能够执行的语言。我们还必须把汇编语言翻译
成计算机能识别的机器语言,这个翻译的过程是在汇编阶段完成的。所以在这个阶段把汇编源文件通过
汇编器生成目标文件(二进制机器语言)。
gcc -c [源文件] -o [目标文件]
实例:gcc -c hello.s -o hello.o
C 语言代码经过编译以后,并没有生成最终的可执行文件(.exe 文件),而是生成了一种叫做目标文件(Object File)的中间文件(或者说临时文件)。目标文件也是二进制形式的,它和可执行文件的格式是一样的。对于 Visual C++,目标文件的后缀是.obj;对于 GCC,目标文件的后缀是.o。
4> 链接 把目标文件执行所依赖的所有二进制的其他目标文件及C的库文件都整合成一个可执行文件的过程需要文件:.o文件及各种动态库或静态库
生成产物:可执行程序。
gcc [源文件] -o [目标文件]
实例:gcc hello.o -o hello
汇编只是将我们自己写的代码变成了二进制形式,它还需要和系统组件(比如标准库、动态链接库
等)结合起来, 链接(Link)其实就是一个“打包”的过程,它将所有二进制形式的目标文件和系统组件组合成
一个可执行文件。
[3]linux下使用sqrt函数问题程序引用头文件math.h;
gcc编译时需要在.c后面加上**-lm**
如:gcc test.c -lm -o test
[4]linux终端左右分屏-
1>安装tmux工具:sudo apt-get install tmux
-
2>使用工具:tmux
-
3>左右分屏:ctrl + b 再按 %
-
4>切换屏幕:ctrl + b 再按 o
-
5>关闭一个终端:ctrl + b 再按x
原因:按下回车键’n’被视为字符,同样进入while循环里的语句判断,造成printf重复执行了两次
解决办法:在获取键盘输入后,加入以下代码,消耗内存中的’n’
while(getchar()!='n')
continue;
[6]输出斐波那契数列前n项以及前n项和(函数+递归)
首先介绍一下斐波那契数列:1、1、2、3、5、8、13、21、34、55……
在数学上,斐波那契数列以递推的方法定义:F(0)=0,F(1)=1, F(n)=F(n - 1)+F(n - 2)(n ≥ 2,n ∈ N*)
代码的实现:
int fibonacci(int n){
return (n==1||n==2)?1:fibonacci(n-1)+fibonacci(n-2);
}
int main(){
int n,fn;
while(1){
int sum = 0;
printf("输入项数/(q->exit):");
scanf("%d",&n);
if(getchar()=='q')
break;
for(int i = 1;i <= n;i++){
fn = fibonacci(i);
sum += fn;
printf("%d ",fn);
}
printf("n前%d项和 = %dn",n,sum);
}
return 0;
}
Ubuntu20.04编译运行测试:
[7]输出二维数组中最大元素以及它的索引思路:先遍历找出最大元素,再遍历每个元素与最大值比较等于就输出它的值以及索引。
代码的实现:
#include[8]冒泡排序(bubble sort)#include int main(){ int arr[3][4]; for(int i = 0;i < 3;i++){ for(int j = 0;j < 4;j++){ arr[i][j] = rand()%30 + 1; } } arr[0][3] =28; for(int i = 0;i < 3;i++){ for(int j = 0;j < 4;j++){ printf("%dt",arr[i][j]); } putchar('n'); } int maxVal = arr[0][0]; int maxIndex1 = 0; int maxIndex2 = 0; for(int i = 0;i < 3;i++){ for(int j = 0;j < 4;j++){ if(arr[i][j] > maxVal){ maxIndex1 = i; maxIndex2 = j; maxVal = arr[i][j]; } } } for(int i = 0;i < 3;i++){ for(int j = 0;j < 4;j++){ if(arr[i][j] == maxVal){ maxIndex1 = i; maxIndex2 = j; maxVal = arr[i][j]; printf("最大元素:arr[%d][%d] = %dn",maxIndex1,maxIndex2,maxVal); } } } return 0; }
排序思路:每次循环把最大的元素放到数组的最后面(排序皆是从小到大)。
代码的实现:
int temp;
bool flag = false;
for (int i = 0;i < N-1;i++){
for(int j = 0;j < N-i-1;j++){
if(arr[j] > arr[j+1]){
temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
flag = true;
}
}
if(!flag){
break;
}else{
flag = false;
}
}
flag的作用:flag是对冒泡排序算法的优化,每次内循环结束都会将长度为N-i-1数组中最大的元素交换到最后面,当内循环结束没有发生数据的交换,说明数组已经是有序的了,此时flag=false,退出循环。
[9]杨辉三角思路:利用了它的排列组合的性质:第n行的第m个数可表示为 C(n-1,m-1),即为从n-1个不同元素中取m-1个元素的组合数。
代码的实现:
#includelong int factorial(int a){ long int p=1; for(int i = 1;i <= a;i++){ p *= i; } return p; } int Cn(int n,int m){ if(m == 1){ return 1; } else{ return factorial(n-1)/(factorial(m-1)*factorial(n-m)); } } int main(){ int n; printf("输入行数(1~20):"); scanf("%d",&n); for(int i = 1;i <= n;i++){ for(int j = 0;j < n-i;j++){ printf(" "); } for(int k = 0;k < i;k++){ printf("%6d",Cn(i,k+1)); } putchar('n'); } return 0; }
运行结果:
使用数组法解决约瑟夫环问题
约瑟夫入狱,监狱内共有33个犯人。某日33名犯人围成一圈,从第一个犯人开始报数,报到数字7的犯人出列,被枪毙,
下一名犯人重新从1开始报数。依次类推,直至剩下最后1名犯人可被赦免。聪明的约瑟夫在心里稍加计算,算出了最后枪毙的位置,他站在这个位置,最终避免了自己被枪毙,逃出升天。
问:约瑟夫算出的是哪个位置?
- 提示:对于约瑟夫环问题来说,需要解决3个问题
- 如何解决数组循环的问题?
- 如何解决“逢7一杀”这个逻辑?
- 如何处理“已死之人”?
代码的实现:
#include#define N 33 #define KILL 7 int main(){ int prisoner[N] = {0}; int counter = 0; int index = 0; int num = 0; while(counter != N-1){ if(index == N){ index = 0; } if(prisoner[index] == 0){ num++; if(num == KILL){ prisoner[index] = 1; counter++; num = 0; printf("第%2d轮报数,%2d号位置的人被嘎了n",counter,index+1); } } index++; } for(int i = 0;i < N;i++){ if(prisoner[i] == 0){ printf("约瑟夫在第%d个位置n",i+1); } } return 0; }
运行结果:



