嵌入式入门学习笔记,遇到的问题以及心得体会!
DAY10
概述:
今日内容不多,C语言大致运用内容完结,后续还有未讲解到的会再讲。
1.封装子函数
2.GDB调试
3.gcc编译流程
笔记:
1,main函数传参
2,递归函数
递归函数:自己调用自己
三步走:
1,什么时候开始?
2,什么时候结束?
3,每一步需要干什么?
1226381826
练习:封装子函数实现二维字符数组的排序(结合switch语句)
三个子函数:1,输入,2,输出,3,排序
(此代码是重点,需反复敲打思考)
#include <stdio.h>
#include <string.h>
#define M 5
#define N 20
int InputTwoStrValues(char (*pstr)[N])
{
//入参检查
if(NULL == pstr)
{
printf("NULL_IN_ERROR!\n");
return -1;
}
int i;
for(i=0;i<M;i++)
{
//输入
//gets(pstr[i]);
scanf("%s",*(pstr+i));
}
return 0;
}
int OutputTwoStrValues(char (*pstr)[N])
{
//入参检查
if(NULL == pstr)
{
printf("NULL_OUT_ERROR!\n");
return -1;
}
int i;
for(i=0;i<M;i++)
{
//输出
printf("%s\n",pstr[i]);
}
return 0;
}
int BubbleSort_Str(char (*pstr)[N])
{
if(NULL == pstr)
{
printf("NULL_BUBB_ERROR!\n");
return -1;
}
int i,j;
for(i=0;i<M-1;i++)
{
for(j=0;j<M-1-i;j++)
{
if(strcmp(*(pstr+j),*(pstr+j+1)) > 0)
{
//交换
char Temp[N] = {'\0'};
strcpy(Temp,*(pstr+j));
strcpy(*(pstr+j),*(pstr+j+1));
strcpy(*(pstr+j+1),Temp);
}
}
}
}
void menu()
{
printf("*******************菜单如下******************\n");
printf("1 ---------------------- 输入字符串\n");
printf("2 ---------------------- 输出字符串\n");
printf("3 ---------------------- 排序字符串\n");
printf("0 ---------------------- 退出程序\n");
printf("*********************************************\n");
}
int main(int argc, const char *argv[])
{
//利用字函数实现二维字符数组的排序,输入,输出
char str[M][N] = {'\0'};
//定义一个行指针来指向该二维字符数组中的第一个字符数组
char (*pStr)[N] = str;
int ret;
while(1)
{
//菜单函数
menu();
printf("请输入需要进行的操作:\n");
int op;
scanf("%d",&op);
if(0 == op)
{
printf("退出成功!\n");
break;
}
switch(op)
{
case 1:
ret = InputTwoStrValues(pStr);
if(-1 == ret)
{
//让程序终止掉
return -1;
}
printf("输入成功!\n");
break;
case 2:
ret = OutputTwoStrValues(pStr);
if(-1 == ret)
{
return -1;
}
printf("输出成功!\n");
break;
case 3:
ret = BubbleSort_Str(pStr);
if(-1 == ret)
{
return -1;
}
printf("排序成功之后的结果为:\n");
ret = OutputTwoStrValues(pStr);
if(-1 == ret)
{
return -1;
}
printf("排序成功!\n");
break;
default:
printf("指令有误,请重新输入!\n");
}
}
return 0;
}
GDB调试:
适用于出现段错误的时候去使用该工具进行调试
调试需要进行以下步骤:
(1)gcc -g test.c -o test
(2)gdb test
(3)设置断点 —》一般从main函数开始进行调试 —> b main
(4)启动 --》 输入r即可
(5)按下n则进行单步调试,不会执行子函数中的语句块,PS:如果想进入子函数,则需按下s,则会将子函数
中的语句块逐一进行调试。
(6)如果找到出错的地方就会出现:segment fault ,此时终止调试
(7)按下q退出即可
#include <stdio.h>
int main(int argc, const char *argv[])
{
int *p = NULL;
*p = 90;
return 0;
}
#include <stdio.h>
#define N 5
void input_func(char **pFunc)
{
int i;
for(i=0;i<N;i++)
{
gets(pFunc[i]);
//gets(*(pFunc+i));
}
}
int main(int argc, const char *argv[])
{
char *p[N] = {NULL};
input_func(p);
int i;
for(i=0;i<N;i++)
{
puts(p[i]);
}
return 0;
}
gcc编译流程:
共分为四个阶段:
(1)预处理:只是做一些简单的文本替换和头文件的展开,不做正确性检查
注意:如果有错误,则会在编译阶段被检测到!!!
gcc -E test.c -o test.i
(2)编译:将上一步生成的.i文件生成汇编文件
gcc -S test.i -o test.s
(3)汇编:将上一步生成的汇编文件生成机器文件
gcc -c test.s -o test.o
(4)链接:将所有的.o文件共同参与链接,生成一个总的APP即可执行文件
gcc test.o -o MyApp
#include <stdio.h>
#define PI 3.1415g26
int main(int argc, const char *argv[])
{
float r = 1.5;
float s;
s = PI * r *r;
printf("s = %.2f\n",s);
return 0;
}
单独编译不链接:指的是编译流程中的前三步!!
练习:
1.运用封装子函数实现非波那契数列的打印
#include <stdio.h>
int Feibonacii_Func(int POS)
{
if(1 == POS || 2 == POS)
{
return 1;
}
else
{
return Feibonacii_Func(POS-1) + Feibonacii_Func(POS-2);
}
}
int main(int argc, const char *argv[])
{
//实现非波那契数列的打印
int count;
printf("请输入需要打印的数列的元素个数!\n");
scanf("%d",&count);
int i;
for(i=1;i<=count;i++)
{
int ret = Feibonacii_Func(i);
printf("%d ",ret);
}
printf("\n");
return 0;
}
2.利用封装子函数实现阶乘
#include <stdio.h>
int cal_mul_func(int argc)
{
if(0 == argc || 1 == argc)
{
return 1;
}
else
{
return argc * cal_mul_func(argc-1);
}
}
int main(int argc, const char *argv[])
{
//利用字函数实现阶乘
int num;
printf("请输入一个需要计算的阶乘的数字:\n");
scanf("%d",&num);
printf("结果为: %d\n",cal_mul_func(num));
return 0;
}
3.利用封装子函数实现递归求和
#include <stdio.h>
int cal_sum_func(int Num)
{
//临界条件判断
if(1 == Num)
{
return 1;
}
else
{
return Num + cal_sum_func(Num-1);
}
}
int main(int argc, const char *argv[])
{
//利用递归实现求和
int num;
printf("请输入一个需要计算的求和数字:\n");
scanf("%d",&num);
int SUM = cal_sum_func(num);
printf("1到%d之间的求和结果为: = %d\n",num,SUM);
return 0;
}