当前位置:首页 > 嵌入式培训 > 嵌入式学习 > 学习笔记 > gcc编译及gdb调试命令详解

gcc编译及gdb调试命令详解 时间:2018-08-10      来源:未知

gcc和gdb

【1】GNU工具

编译工具:把一个源程序编译为一个可执行程序

调试工具:能对执行程序进行源码或汇编级调试

软件工程工具:用于协助多人开发或大型软件项目的管理,如make【2】gcc简介

全称为GNU CC ,GNU项目中符合ANSI C标准的编译系统

【3】gcc编译过程

1--- 预处理:主要进行宏替换以及头文件的包含展开

gcc -E HelloWorld.c -o HelloWorld.i

2--- 编译:编译生成汇编文件,会检查语法是否有错误

gcc -S HelloWorld.i -o HelloWorld.s

3--- 汇编:将汇编文件编译生成目标文件(二进制文件)

gcc -c HelloWorld.s -o HelloWorld.o

4--- 链接:链接库函数,生成可执行文件

gcc HelloWorld.o -o HelloWorld

【4】Gdb调试

首先使用gcc对file.c进行编译,注意一定要加上选项‘-g’

查看文件(list)

(gdb) l

一次十行,知道显示完为止

l 1 回到先前的位置

设置断点 (break)

(gdb) b 行数

删除断点 (delete)

del 1删除第一个断点

查看断点情况

(gdb) info b

查看变量值(print) 也可以查看变量的地址 p &a

(gdb) p n

单步运行 (next step)

(gdb) n

(gdb) s 进入函数

恢复程序运行 (continue)

(gdb) c

帮助

(gdb) help [command]

退出

q

gdb使用时注意事项

在gcc编译选项中一定要加入‘-g’。

只有在代码处于“运行”或“暂停”状态时才能查看变量值。

设置断点后程序在指定行之前停止

运行被调试程序,设置所有的能影响该程序的参数和变量。

保证被调试程序在指定的条件下停止运行。

当被调试程序停止时,让开发工程师检查发生了什么。

根据每次调试器的提示信息来做响应的改变,以便修正某个错误引起的问

***************************指针***********************

【1】指针定义

在计算机内部存储器(简称内存)中,每一个字节单元,都有一个编号,称为地

址。

在C语言中,内存单元的地址称为指针,专门用来存放地址的变量,

称为指针变量(pointer variable)。在不影响理解的情况中,有时对地址、指针和指针变量不区分,通称指针。

*:在定义指针变量时,只起到标识作用,在其他情况下,代表获取指针变量内的内

&:代表取变量的地址

int *p = &a;

//如果一个指针变量指向NULL,代表不给他分配任何地址

int *q = NULL;

printf("q = %p\n", q);

输出结果为:q=(nil)

//指针变量只能指向一块已经开辟的空间

//int *n = 0x12345678;

错误,变量的地址只能由系统分配,不能人为指定

//地址的运算与数据类型相关

printf("p = %p\n", p);

printf("p + 1 = %p\n", p + 1);

【2】指针与一维数组

//数组名是一个地址常量,不能改变地址

int a[6] ;

a++; 错误,a为地址常量,不可更改 int b[N];

b = a; 错误,b为地址常量,不可更改

指针的升级 int a[6] ; &a 代表整个数组a的地址,&a+1 代表移动整个数组的大小

printf("&a = %p\n", &a);

printf("&a + 1 = %p\n", &a + 1);

【3】指针与二维数组

1)指针的升级 &a 代表整个数组,&a+1 代表移动整个数组的大小 int a[3][4];

printf("&a = %p\n", &a);

printf("&a + 1 = %p\n", &a + 1);

2)二维数组的名字为行指针,指向a[ 0 ] 元素,a+1每次移动一行元素的大小 printf("a = %p\n", a);

printf("a + 1 = %p\n", a + 1); 3)指针的降级,将行指针降级为列指针

*a 代表将行指针a降级为列指针,指向元素a[0][0],*a+1,移动一个元素的大小 printf("*a = %p\n", *a);

printf("*a + 1 = %p\n", *a + 1);

4)a[0] 为列指针,指向元素a[0][0], a[0]+1,移动一个元素的大小

printf("&a[0][0] = %p\n", &a[0][0]); printf("&a[0][0] + 1 = %p\n", &a[0][0] + 1);

【4】字符指针和字符串

1)字符串自带结束标志符‘\0’

char s1[] = "hello";

char s2[6] = {'h', 'e', 'l', 'l', 'o', '\0'};

char s2[5] = {'h', 'e', 'l', 'l', 'o'}; 数据后没有结束符,易发生越界访

2)字符指针指向一个字符串常量,不可更改字符串的内容,但是可以更改字符指针的

指向

【5】数组指针

数组指针:本质上一个指针,指针指向一个数组,就是一个行指针

int (*p)[4]; //4为列数

【6】指针数组

指针数组:本质上是一个数组,数组里面存放的是指针

int *p[2]; // [2] 为数组的长度,表示数组内可以存储两个指针

【7】多级指针

多级指针:指向指针的指针

int *p = &a; int **q = &p; 【8】const

const常用来修饰指针变量或者类型

1)如果const修饰类型,则不能通过指针变量修改数据 const int *p = &a;

*p = 40; 错误,不可通过*p访问数据内容

2)如果const修饰一个指针变量,则不能呢个改变这个指针变量的地址

int *const p = &a;

p = &b;错误,不可更改p的指向注意:const 修饰谁,谁被常量化,不可更改

******************函数********************【1】定义

函数是一个完成特定功能的代码模块,其程序代码独立,通常要求有返回值,也可以是空值。

【2】一般形式如下:

<数据类型> <函数名称>( <形式参数说明> )

{

语句序列;

return (<表达式>);

}

其中:

<函数名称>是一个标识符,要求符合标识符的命名规则;

<数据类型>是整个函数的返回值类型,如无返回值应该写为void型;

<形式参数说明>是逗号”,”分隔的多个变量的说明形式,通常简称为形

参;

大括弧对 {<语句序列> },称为函数体;

<语句序列>是大于等于零个语句构成的。

注意:在函数体中,表达式语句里使用的变量必须事先已有说明,否则不

能使用。

return(<表达式>)语句中表达式的值,要和函数的<数据类型>保持一致;如函数的<数据类型>为void,可以省略或者无表达式结果返回(即写成

return ;)。

【3】函数传参

值传递 :函数的传参1:值传递,只是将变量的数据传递给行参,不会改变原来实参的数据

地址传递 将变量的地址传递给行参,改变地址的内容,则实参也会改变

注意:数组的值传递,实质为地址传递,改变形参的值,实参的值同样被改变【4】命令行传参(向main函数传递参数)

argc:表示命令行传参的个数

argv:表示命令行所传的每一个参数

【5】函数指针

函数指针:本质上是一个指针,指向一个函数

注意:函数名就是首地址

【6】指针函数

指针函数:本质上是一个函数,返回值是一个指针

【7】函数指针数组

函数指针数组:本质上是一个数组,数组里面存放的时函数指针

【8】递归函数

在递归函数中判断是否满足某个条件,不满足则return 递归函数本身

(return myrecursion)

满足条件则返回一个准确的数值

int myrecursion(int n){

if(n<1)

return 1;

else

return n*myrecursion(n-1);

}

 

【9】回调函数

将一个函数以参数的形式传递给某个函数。

即回调函数的其中之一或更多的形参是某个函数传参使用函数名

int callback(int fun(int a,int b),int m,int n){ return fun(m,n);

}

上一篇:linux命令大全--分类总结、实例和用法

下一篇:NFS服务端和ftfp客户端配置的详细步骤

热点文章推荐
华清学员就业榜单
高薪学员经验分享
热点新闻推荐
前台专线:010-82525158 企业培训洽谈专线:010-82525379 院校合作洽谈专线:010-82525379 Copyright © 2004-2022 北京华清远见科技集团有限公司 版权所有 ,京ICP备16055225号-5京公海网安备11010802025203号

回到顶部