C语言学习入门到精通之gcc编译与调试

原创 2016年05月30日 12:36:15

在linux系统下进行C语言开发的学习

    在linux系统下,C语言的编译是由gcc编译器(即释译工具)完成的

    arm-linux-gcc 是arm的编译器即编译的是运行在arm开发板上的程序

    arm-android-gcc 是android的编译器

   
    参数:

         -o    指定生成的目标

         -E   预处理 即把所有的带#的编译指令替换为标准C (预处理指令不是标准C指令)   gcc -o test.i  -E test.c  //  -E 预处理  -o 目标文件

</pre>         -S   编译成汇编     gcc  -o test.s -S test.i    <p></p><p>         -c   编译机器码 (机器码:即机器语言)    gcc  -o  test.o  -c  test.s</p><p>         gcc   -o    test    test.o    //-o   目标为可执行程序, .o为依赖的机器码文件   </p><p>     三合一    直接生成.o</p><p>     gcc   -o  test.o -c  test.c  </p><p>     四合一</p><p>     gcc   -o  test  test.c  </p><p>     注意: 在将.o文件(机器码)编译成可执行程序的过程还包含一个链接的过程,在编写应用程序的情况下,把这一块封装了,在后面的博客中会进一步的详细的描述 。 </p><p></p><h3>多文件的编程与编译</h3><p>     多文件编程指的是: main(即入口函数)在一个.c 文件中,在这一个.c 中需要使用其它.c 中的函数或数据,那么其它.c文件需要提供.h文件作为接口。特别是在模块化开发时更应该使用多文件编程的方式开发。</p><p>     1).h 的写法</p><p>          </p><pre name="code" class="cpp">#ifndef 宏名      //假设 该宏名没有定义,则编译下面代码
#define 宏名     //定义宏
    扩展声明
#endif             //结束编译条件
    宏名的规范写法: 头文件的名称的大写 . 变成 _    例如:头文件名称是:helle.h   则宏名可以使 HELLO_H
     2)声明和扩展声明

        

int max(int x.int y);    //函数的声明
int main(int argc,char **argv)
{
    int a=12;
    int b=23;
    int c=max(a,b);  //函数的调用
}

int max(int x,int y)  //函数定义
{
    return x>y?x:y;
}

     3)静态声明以及扩展声明

          static 修饰函数,代表这个函数只能在本文档中使用  (使用条件:不希望该函数被其它.c文件所调用,只是对外提供接口)

          不用static 修饰的函数,代表全局函数,可以在任意文件中使用,但在编译时会找不到该函数,所以需要使用extern 作外部声明(在.h文件中)   

例子;
//fun.h
#ifndef FUN_H
#define FUN_H
extern int max(int x,int y);  //扩展声明
#endif

//fun.c
int max(int x,int y) //函数定义
{
    return x>y?x:y;
}

//test.c
#include<stdio.h>
#include"fun.h" //引入头文件(编译时会进行替换-extern int max(int x,int y);  )
int mian(itn argc,char **argv)
{
    int a;
    int b=23;
    int c=max(a,b);
}

程序的调试

1、代码错误

     (1)语法错误(哈哈  自己解决吧!!!   在这我也没办法一一指出,在后续的博客更新中,我会贴上我自己代码编写过程中遇到的语法错误)

     (2)找不到.h文件 

              1)在.c文件中,#include“目录/头文件”

              2)编译时用 -I 来指定头文件位置              gcc -o test test.c  ./lib/fun.c   -I  ./lib      


2.段错误

      (1)参数需要的是内存地址,而给到的是其它类型          例 :scanf("%d %d",&a,b);

      (2)定义了一个指针变量 ,而指针变量中没有赋地址值

             

     int *p;
     scanf("%d",p);
         注意:通常定义一个指针变量后,一定使用malloc或new 分配内存进而初始化或者使用NULL进行初始化,在释放malloc或mew分配的内存后,一定使用NULL对该指针变赋值
      


3、编译或运行出错的调试方法
  1)printf打印法

   int main(int argc,char *argv[]){
       printf("--------------- 1\n");
       int a=12;
       int b=0;
       printf("--------------- 2  a=%d,b=%d\n",a,b);
       int c=a/b;
       printf("--------------- 3\n");
       printf("---- %d\n",c);
       printf("--------------- 4\n");
   }
   程序员常用方法 如果2打印,而3未打印,则代表2与3之间出现错误
         
 2)调试工具法
   编译时必须用 -g参数编译,然后用gdb调试,如下:
        gcc -g -o test test.c fun.c
        gdb ./test
   当进入gdb后可使用如下指令
        l [n][fun] 查看代码  
        例:  l 查看所有代码  
                 l 3 查看第三行周围的代码  
                 l max 查看max函数
        b [文件名:][n][fun] 设置断点  
        例:  b 3 在第三行设置断点  
                 b max 在函数max处设置断点
        r 从前向后运行  遇到断点处停止
        p 打印信号     
       
        n 单步执行 不会进入函数
        u 单步执行 可跳出循环
        s 单位步执行,可以进入函数内部
           
        例:p a 打印变量a的值
               p &a 打印a的地址
               p a+2 打印变量a加2后的值
        info break 查看断点信息

     注意:我个人更加喜欢printf调试方法,不解释

      ps:在嵌入式方面遇到的问题,希望大家能够与我一起进行讨论共同进步,个人邮箱:983177739@qq.com(只能留个QQ邮箱,虽然比较low,但不惧垃圾邮件,哈哈,因为垃圾邮件已经够多了)



版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

GCC编译初步 ubuntu c语言入门知识

C 编程中相关文件后缀 .a 静态库 (archive) .c C源代码(需要编译预处理) .h C源代码头文件 .i ...

linux下GCC编译环境中二叉树遍历、C语言实现以及调试过程中段错误

最近一直在学习数据结构准备面试,昨天晚上看到了二叉树,在网上查了一些资料以后照猫画虎的写了一个二叉树遍历的程序,主要是为了消化递归构建二叉树和遍历的过程,调试过程中也发现了不少问题。 二叉树概念属性...

c语言编译gcc

  • 2015-12-03 20:47
  • 12.43MB
  • 下载

c语言库函数和头文件以及gcc下编译工程

一:windows下.dll动态链接库(相当于linux下的.a和.so文件,是源文件经过编译后的文件) 在Windows世界中,有无数块活动的大陆,它们都有一个共同的名字——动态链接库。现在就走进...

重学c语言系列一(gcc编译过程)

此系列文章的目的:1.希望能够掌握之前理解不清楚和根本没有掌握的知识点                                 &#...

通过GCC编译器编译c语言

GCC编译C源代码有四个步骤:预处理—->编译—->汇编—->链接。可以利用GCC的参数来控制执行的过程,这样就可以更深入的了解编译C程序的过程。下面将通过对一个程序的编译来演示整个过程。#inclu...

gcc编译命令----小话c语言(14)

[Mac 10.7.1  Lion  Intel-based  x64  gcc 4.2.1] Q: 如何让编译的文件可以被gdb调试? A: 可以加入-g参数。如下代码,保存为hello...

菜鸟攻略–C语言多文件编程初探(二):使用 gcc 手动编译多文件 C 程序

菜鸟攻略–C语言多文件编程初探(二):使用 gcc 手动编译多文件 C 程序四年前我发布了一篇菜鸟攻略–C语言多文件编程初探(一),没想到这篇文章成了我博客上阅读量最多,评论数也最多的文章。当时我读大...

ubuntu下用Gcc编译器编译c语言的静态和动态链接库范例

我在一个目录下新建hello.h hello.c main.c三个文件,我们需要将hello.c文件编译成静态库以及动态库。在存放文件目录下打开一个终端。三个文件hello.h(见程序1)为该函数库的...

JAVA对比C语言,从入门到精通学习JAVA

Java和C以及C++的都是高级语言,相比于汇编,或者机器语言的01代码,无疑大大简化了程序员的编程工作,三者很多基础语法结构类似,尤其是JAVA与C++,有一门的基础往往其他几种语言掌握起来会非常容...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)