Linux gcc/g++使用

编译:预处理/编译/汇编/链接
(1)预处理:头文件展开,去注释,宏替换,条件编译。生成(.i)文件
(2)编译:将c代码翻译形成汇编代码。生成(.s)文件
(3)汇编:将汇编形成目标二进制文件。生成(.o)文件
(4)链接:将目标文件和系统库进行链接形成可执行程序(可执行程序)
Linux指令:

cat helloworld.c
gcc -E helloworld.c -o helloworld.i//预处理之后的文件
gcc -S helloworld.i -o helloworld.s//汇编语言
gcc -c helloworld.s -o helloworld.o//目标文件
od helloworld.o//以八进制形式打开目标二进制文件
 

上下键翻阅历史命令,Ctrl+人命令可以进行历史命令搜索。ctrl+c退出搜索。

gdb 命令调试:

Linux默认生成的可执行程序是动态链接且以release方式发布的!

gcc hello.c -o hello -g
//让程序以debug形式发布,debug方式会给程序内部添加调试信息,
//能够让程序可被调试

在这里插入图片描述
#如果程序要被调试,gcc必须携带 -g 选项。debug方式会给程序内部添加调试信息。

readelf -S hello -d | grep debug
//查看可调式信息

在这里插入图片描述

gdb + 可执行文件          开始调试
断点:        b 行号
删除断点:    d 后面跟断点编号
禁用断点:    disable  num
启用断点:    enable num
查看断点信息:info break
**跳转到指定断点处执行:c or continue**//对代码进行分区
until num :跳转到特定行号
查看代码:    l or list 行号
运行程序:    r  or run
进入函数(逐语句): s  or step 
逐过程:      n  or  next
查看变量内容: p 变量
常显示:      display + 变量名。
取消常显示:   undisplay + 编号。
finish : //运行完当前函数,逐个检查每个函数运行是否正常

一旦源程序被修改,一定要进行重新编译,不然debug调试就不准。

make && Makefile

一个工程中的源文件不计数,其按类型、功能、模块分别放在若干个目录中,makefile定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作。
makefile带来的好处就是——“自动化编译”,一旦写好,只需要一个make命令,整个工程完全自动编译,极大的提高了软件开发的效率。
make是一个命令工具,是一个解释makefile中指令的命令工具,一般来说,大多数的IDE都有这个命令,比如:Delphi的make,Visual C++的nmake,Linux下GNU的make。
make是一条命令,makefile是一个文件,两个搭配使用,完成项目自动化构建。

下面是makefile的两种写法:

在这里插入图片描述
在这里插入图片描述

main:main.o cal.o
	gcc -o $@ $^
%.o:%.c
	gcc -c $<

.PHONY:clean
clean:
		rm -f *.o main

编译文件,编译器是如何知道我的生成软件需要被重新编译?
根据文件的修改时间来的,因为用户不可能同时修改多个问题所以文件的修改总是有先后顺序的。

缓冲区

在这里插入图片描述
运行上述代码时,出现疑似先执行sleep(5)后执行printf的情况。
实则不然,C(任何语言)程序在运行的时候,默认永远是从上到下执行,除非for,函数,if,等,一定是先执行 printf(字符串被写到C程序的缓冲区中,但并没有别的输出!!)再执行sleep,sleep结束,缓冲区内容被刷新,才能看到字符串的输出。
缓冲区:就是一块内存,刷新策略,行刷新/程序结束/强制刷新。
C程序在默认情况下会打开三个文件(3个设备:键盘,显示器,显示器)分别对应,FILE*,stdin,stdout,stderr。
![在这里插入图片描述](https://img-blog.csdnimg.cn/20210310104309642.png在这里插入图片描述
这里改变了刷新策略后 ,输出就没有出现延迟。

\r && \n

\r 回车
\n 换行
memset函数

1.void *memset(void *s,int c, size_tn)
作用:将已开辟内存空间 s 的首 n 个 字节的值设为值 c。
y9ibG9nLmNzZG4ubmV0L2R1MTIzMg==,size_16,color_FFFFFF,t_70)

学习这个函数之后,我们实现一个进度条代码

//1: proc.c                                                                                                             ?? buffers 
  #include"proc.h" 
  void proc()
  {
    
    
  	char bar[NUM];
    memset(bar,'\0',sizeof(bar));
    const char *lable="|/-\\";
    int i = 0;
    while(i < 100)
   {
    
    
     fflush(stdout);
     bar[i++] = '#';
     usleep(100000);
     printf("[%-100s][%3d%%][%c]\r",bar,i,lable[i%4]);                                                                             
   }
    printf("\n");
 }
//proc.h
#pragma once

#include<stdio.h>
#include<string.h>
#include<unistd.h>
#define NUM 101
extern void proc();

//main.c
#include<stdio.h>
#include<string.h>
#include<unistd.h>
#define NUM 101
extern void proc();
[duke@VM-0-3-centos proc]$ cat main.c
#include"proc.h"
int main()
{
    
    
  proc();
  return 0;
}

猜你喜欢

转载自blog.csdn.net/du1232/article/details/114457553