Linux周笔记

文章详细阐述了GCC的编译步骤,包括预处理、编译、汇编和链接,并讨论了参数传递的选择,如指针和二级指针的使用场景。此外,还介绍了动态内存管理函数如malloc和free,以及结构体、枚举、递归函数的概念。最后,提到了调试技巧,如使用gdb,以及Makefile在多文件编译中的作用和基本用法。
摘要由CSDN通过智能技术生成
  1. gcc编译流程:

第一步:预处理--》将C原文件编译成C文件

文件展开,注释去掉,宏替换去掉,不做语法检查

gcc  -E  test.c  -o  test.i

第二步:编译--》将预处理之后的C文件编译成汇编文件

gcc  -S  test.i  -o  test.s

第三步:汇编--》将汇编文件编译生成机器文件

gcc  -c  test.s  -o  test.o

第四部:链接--》将所有的机器文件共同参与链接,生成一个可执行文件

Gcc   *.o  -o  app

  1. 对于传参,到底是传普通变量还是传一级指针变量,又或者是传二级指针变量的选择思路

看是否需要在子函数内部引起实参本身发生改变

int a = 90,b = 89,

在子函数中实现ab两个数交换(在子函数中引起实参ab本身发生改变,因此需要将ab

的地址传过去)---func(&a,&b)

Int *p =null;

子函数中实现给实参p赋值一个连续的空间首地址,子函数中引起实参p发生改变,此时p会具备一个首地址,因此需要将&p传过去

Func(&p)-->pointer = &p  *pointer = p 因此通过给*pointer赋值就相当于给实参p赋值

  1. 指针函数

函数返回值类型是指针类型的函数

  1. 函数指针

指向函数的指针

命名方式:返回值类型(*pfunc)(形参列表)

针对函数指针类型取别名的写法:

返回值类型 (*新类型名)(形参列表);

  1. 函数指针数组

数组元素类型是函数指针类型的数组

定义:

     函数指针类型  数组名[元素个数]; //取完别名之后可以这样定义函数指针数组

     返回值类型 (*数组名[元素个数])(参数表列表);

  1. 回调函数

把B函数的地址(即函数名或者&函数名)作为A函数的参数,传递给A函数,在A函数中通过使用这个参数间接调B函数的过程称为回调函数

  1. 动态内存管理
  1. 申请空间

Void *malloc(size_t  size);

功能:申请空间在堆区中

       参数:所需申请空间占据的字节数

       返回值:成功返回连续空间的首地址,失败返回NULL

void *calloc(size_t nmemb, size_t size);

       功能:申请空间

       参数:

           参数1:所需申请的元素个数

           参数2:元素的大小(字节数)

           返回值:成功返回连续空间的首地址,失败返回NULL

               注意:calloc在申请完空间之后,会自动将申请的连续空间初始化为’\0’

  1. 释放空间

void free(void *ptr);

       功能:释放空间

       参数:所需释放空间的首地址

       返回值:无返回值

  1. 扩容空间

void *realloc(void *ptr, size_t size);

       功能:用来扩容空间

       参数:

            参数1:所需扩容空间的首地址(malloc的返回值)

            参数2:扩容之后总的字节数(旧 + 新)

       返回值:成功返回扩容之后空间的首地址,失败返回NULL

               注意:扩容之后的空间首地址可能和之前的地址一样,也可不一样!!!

       头文件:

              #include <string.h>

  1. 重置空间

void *memset(void *s, int c, size_t n);

  功能:用来重置一片内存空间  (当做清空空间居多!

参数:

     参数1:所需重置内存空间首地址

     参数2:所需重置的字符 ---》\0 , 0

     参数3:所需重置内存空间的大小---》sizeof()

 

  1. 结构体

概念:是一种构造类型,目的是为了将一个事物的多重属性表示清楚(可是不同属性也可以是相同得到数据类型)

如何构造一个结构类型:

struct 结构体名

{

数据类型1  成员1 ;

数据类型2  成员2;

。。。。

数据类型N  成员N;

};

如何定义结构体变量

Struct  结构体名  变量名;

如何给结构体成员赋值:

变量名= {值1,值2.。。。。。。};

struct 结构体名 变量名 = {值1,值2,。。。。。};

如何访问结构体中的成员:

方式1:变量名.成员名;

方式2:结构体指针->成员名;

  1. 枚举

概念:跟宏比较类似,意味着也是一些常量值,只不过这些常量值是被放在一个集合里面。

如何定义一个枚举类型?

enum 枚举名

{

枚举数值名1,

枚举数值名2,

。。。。

};

  1. 大小端(字节序)
    大端存储:低字节处的内容存储在高地址处,高字节处的内容存储在低地址处

小端存储:低字节处的内用存储在低地址处,高字节出的内容存储在高地址处

低字节:一串二进制数据的右边

低地址:小的地址编号

  1. 调试BUG的方式

gdb调试工具

       流程:

  1. 生成带有调试信息环境的可执行文件

     方式:gcc  -g   test.c  -o  App

  1. 进入该可执行文件

     方式:gdb  App

  1. 设置断点 -->让程序从哪里开始调试

   方式:b  行标/函数名

  1. 运行

     方式: r

  1. 单步运行

      n: 不进入子函数内部,但不代表不执行子函数

s: 进入子函数内容,并开始执行子函数中每一行代码

  1. 找到错误所在的行

     响应:看到程序打印出一行文本“Program recived Sigmentation fault....”,上一行就是引起错误的所在行。

  1. 结束调试

     方式:按下q退出即可。

  1. 递归函数

概念:重复调用其他函数或者调用自己,但是调用的时候一定要注意结束调用的条件。

如何编写一个标准的递归函数?

三要素:

  1. 从哪里开始?
  2. 从哪里结束?
  3. 每一步干什么?

使用递归函数完成斐波那契数列的打印

1 1 2 3 5 8 13 21.。。。。。。。

实现要求:输入需要打印的个数N,就输出对应的前N项。

多文件编译

创建一个后缀是.h文件eg: touch  test.h

打开test.h  ---> vim  test.h

编写以下代码:

#ifndef _TEST_H_

#define _TEST_H_

  1. 宏定义
  2. 结构体定义
  3. 取别名
  4. 全局变量的声明
  5. 函数的声明
  6. 枚举类型的定义

#endif

Vim -p 同时打开多个文件进行编辑

Xa 退出并保存多个文件

  1. Make

概念:工程管理工具

可以将很多.c文件+.h文件进行统一管理

使用:

     命令行输入make 目标名  即可

如何编写一个Makefile文件?

---》统一格式

目标:依赖

[Tab]命令表

嵌套Makefile

Make中的变量

  1. 用户自定义变量

格式:

变量名:=值   (定义变量且赋初值,变量名建议大写)

  1. 自动变量

$< :依赖中的第一个依赖

$^ :所有依赖

$@:目标名

$()----取值

  1. 系统预定义变量

CC:编译器的名称,默认值是cc ,用户可以自己赋值为: eg  CC :=cc

CFLAGS:编译器的选项,无默认值,用户可以自己赋值:eg: CFLAGS:= -c  -g   -Wall

RM:代表删除,默认值为:rm  -f,用户可以自己赋值为 eg: RM := -rf

  1. 环境变量

export :添加一些指定的环境变量到整个系统环境中去

eg:

   export  变量1  变量2  变量3

  1. make -C 指定某个路径

Make -C ./src------>执行src下的单makefile

Make -C ./obj------>执行obj下的单makefile

  1. Makefile文件中“#文字说明”:相当于注释

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值