UC成长之路2

本文介绍了C语言程序的开发流程,包括头文件的编写、静态链接、静态库的制作和使用,以及使用gdb进行调试。讲解了从源文件编译到生成可执行文件的过程,nm命令的使用,以及如何通过gcc命令指定静态库和路径。同时,探讨了环境变量的作用,特别是PATH变量在程序执行中的意义。最后,提到了bash中的特殊环境变量PS1和如何设置。
摘要由CSDN通过智能技术生成

回顾:
UC成长之路1

UC成长之路2

一、大型软件的组织(链接,静态链接)

  • 鸡窝 工程特别小
  • 盖一座楼 楼层
    设计 | 概要设计 | 框架设计
    窗户 | 门子 | 长宽高 | 详细设计 | 组件设计
    多道工序 | 并行 | 并行开发

协议 | 接口 | 函数 | 函数的声明
类型的定义 | 宏定义
将这些东西放到一个文件中 | 头文件

头文件中
/*头文件卫士*/
#ifndef 宏
#define 宏
1.函数声明
2.类型的定义
3.变量的声明
4.包含文件
5.宏定义
#endif 

题外话:变量的声明和变量的定义的区别?
变量的声明不需要分别配空间,定义要分配空间。

单元测试->集成测试

举例说明:主函数中调用函数完成加减乘除的功能

  • 先定义接口文件

编译的基本单位是源文件

补充:
nm 二进制文件名:查看二进制文中的符号表
图中的T表示文件中有该函数的实现,U表示文件使用到相关的函数但是没有实现代码在文件中

在这里插入图片描述

weeks@weeks-virtual-machine:~/workSpace/codeofc/pmath$ gcc math.o add.o
weeks@weeks-virtual-machine:~/workSpace/codeofc/pmath$ ls
add.c  add.o  a.out  math.c  math.o  mul.c  mul.o  pmath.h
weeks@weeks-virtual-machine:~/workSpace/codeofc/pmath$ nm a.out
0000000000601040 B __bss_start
0000000000601040 b completed.7594
0000000000601030 D __data_start
0000000000601030 W data_start
00000000004004a0 t deregister_tm_clones
0000000000400520 t __do_global_dtors_aux
0000000000600e18 t __do_global_dtors_aux_fini_array_entry
0000000000601038 D __dso_handle
0000000000600e28 d _DYNAMIC
0000000000601040 D _edata
0000000000601048 B _end
0000000000400654 T _fini
0000000000400540 t frame_dummy
0000000000600e10 t __frame_dummy_init_array_entry
00000000004007f0 r __FRAME_END__
0000000000601000 d _GLOBAL_OFFSET_TABLE_
                 w __gmon_start__
000000000040067c r __GNU_EH_FRAME_HDR
0000000000400400 T _init
0000000000600e18 t __init_array_end
0000000000600e10 t __init_array_start
0000000000400660 R _IO_stdin_used
                 w _ITM_deregisterTMCloneTable
                 w _ITM_registerTMCloneTable
0000000000600e20 d __JCR_END__
0000000000600e20 d __JCR_LIST__
                 w _Jv_RegisterClasses
0000000000400650 T __libc_csu_fini
00000000004005e0 T __libc_csu_init
                 U __libc_start_main@@GLIBC_2.2.5
0000000000400566 T main
00000000004005b5 T p_add
                 U printf@@GLIBC_2.2.5
00000000004005c9 T p_sub
                 U puts@@GLIBC_2.2.5
00000000004004e0 t register_tm_clones
0000000000400470 T _start
0000000000601040 D __TMC_END__

命令gcc math.o add.o -v可以将链接情况显示出来

weeks@weeks-virtual-machine:~/workSpace/codeofc/pmath$ gcc math.o add.o -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/5/lto-wrapper
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu 5.4.0-6ubuntu1~16.04.12' --with-bugurl=file:///usr/share/doc/gcc-5/README.Bugs --enable-languages=c,ada,c++,java,go,d,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-5 --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-vtable-verify --enable-libmpx --enable-plugin --with-system-zlib --disable-browser-plugin --enable-java-awt=gtk --enable-gtk-cairo --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-5-amd64/jre --enable-java-home --with-jvm-root-dir=/usr/lib/jvm/java-1.5.0-gcj-5-amd64 --with-jvm-jar-dir=/usr/lib/jvm-exports/java-1.5.0-gcj-5-amd64 --with-arch-directory=amd64 --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --enable-objc-gc --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
Thread model: posix
gcc version 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.12) 
COMPILER_PATH=/usr/lib/gcc/x86_64-linux-gnu/5/:/usr/lib/gcc/x86_64-linux-gnu/5/:/usr/lib/gcc/x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/5/:/usr/lib/gcc/x86_64-linux-gnu/
LIBRARY_PATH=/usr/lib/gcc/x86_64-linux-gnu/5/:/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/5/../../../../lib/:/lib/x86_64-linux-gnu/:/lib/../lib/:/usr/lib/x86_64-linux-gnu/:/usr/lib/../lib/:/usr/lib/gcc/x86_64-linux-gnu/5/../../../:/lib/:/usr/lib/
COLLECT_GCC_OPTIONS='-v' '-mtune=generic' '-march=x86-64'
 /usr/lib/gcc/x86_64-linux-gnu/5/collect2 -plugin /usr/lib/gcc/x86_64-linux-gnu/5/liblto_plugin.so -plugin-opt=/usr/lib/gcc/x86_64-linux-gnu/5/lto-wrapper -plugin-opt=-fresolution=/tmp/ccvp8A9P.res -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lc -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_s --sysroot=/ --build-id --eh-frame-hdr -m elf_x86_64 --hash-style=gnu --as-needed -dynamic-linker /lib64/ld-linux-x86-64.so.2 -z relro /usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/crt1.o /usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/crti.o /usr/lib/gcc/x86_64-linux-gnu/5/crtbegin.o -L/usr/lib/gcc/x86_64-linux-gnu/5 -L/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu -L/usr/lib/gcc/x86_64-linux-gnu/5/../../../../lib -L/lib/x86_64-linux-gnu -L/lib/../lib -L/usr/lib/x86_64-linux-gnu -L/usr/lib/../lib -L/usr/lib/gcc/x86_64-linux-gnu/5/../../.. math.o add.o -lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed /usr/lib/gcc/x86_64-linux-gnu/5/crtend.o /usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/crtn.o

gcc main.o add.o
链接发生在编译链接成可执行文件的时候,可执行还没有执行的阶段。
静态链接
程序的入口是_start,c程序的入口是main函数
c语言是由函数组成的。函数之间的调用和被调用的关系。

  • 补充知识:
    • 终端命令:echo 字符串将字符串输出到显示器
    • echo $?:将上一个进程的执行结果显示在显示器终端上
int main(void){
	return 0;
}

生成a.out文件后运行,再使用echo $?显示0

二、静态库文件的制作和使用

  • 库文件:函数库(动态库文件,静态库文件)
  • 静态库文件是在编译的时候添加到可执行文件中,而动态库文件是在可执行文件加载到内存运行时才添加到可执行文件中
  • 静态库文件的命名规则:lib库名.a
  • 静态库文件制作和使用步骤:
    • 将要加入到库文件的所有源文件编译成目标文件
      在这里插入图片描述
    • 将要加入到库文件中的所有函数打包成静态库文件, 命令是:ar -r libmath.a *o
      在这里插入图片描述
    • 使用静态库文件链接生成可执行文件
      在这里插入图片描述
      -L路径 存放静态库文件的路径名
      -l库名
/*math.h*/
#ifndef __T_METH_H__
#define __T_METH_H__

int add(int, int);
int sub(int, int);
int mul(int, int);
int div(int, int);

#endif //__T_METH_H__


/*main.c*/
#include <stdio.h>
#include "day02/tmath.h"
int main(void)
{
    int a=6, b=2;
    printf("6+2=%d\n", add(6, 2));
    printf("hello beijing\nvim");
    return 0;
}


/*add.c*/
#include "tmath.h"

int add(int x, int y)
{
    return x+y;
}

int sub(int x, int y)
{
    return x-y;
}


/*mul.c*/
#include "tmath.h"

int mul(int x, int y)
{
    return x*y;
}

int div(int x, int y)
{
    return x/y;
}

#include <> 和 #include " "的区别?
<>是系统指定的路径下找头文件。gcc -c main.c -v
在这里插入图片描述
使用头文件pmath.h方法有三种方法:

  • #include “jingtai/pmath.h”//将路径写清楚
  • 将头文件复制到系统路径下,可以使用gcc -c main.c -v查看程序所需要的文件所在的系统路径信息,将头文件添加到其中的一个路径下
  • 可使用命名gcc -c main.c -Ijingtai -v,将头文件的路径暂时添加在系统路径下
    在这里插入图片描述

三、gdb调试工具的使用

要调试的文件是可执行文件,在这个可执行文件中必须要有调试信息。
如何生成一个具有调试信息的可执行文件呢?
gcc -c main.c jingtai/*.c -Ijingtai -g

gcc -c main.c jingtai/*.c -Ijingtai -ggdb
在这里插入图片描述
启动gdb:gdb a.out
gdb的命令选项:

  • l:list 列出程序的源代码
  • b 行号|函数的名字:设置断点
  • r:run 运行
  • n:next 运行下一语句
  • p:print 打印
  • q:quit 退出gdb
  • s:step 切入到调用函数中
weeks@weeks-virtual-machine:~/workSpace/codeofc$ gdb a.out
GNU gdb (Ubuntu 7.11.1-0ubuntu1~16.5) 7.11.1
Copyright (C) 2016 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from a.out...done.
(gdb) l
1	#include <pmath.h>
2	#include <stdio.h>
3	//框架
4	int main(void)
5	{
6		int a=6, b=2;
7		printf("%d+%d=%d\n", a, b, p_add(a,b));
8		//組件
9		printf("hello beijing\n");
10		return 0;
(gdb) b main
Breakpoint 1 at 0x40056e: file main.c, line 6.
(gdb) r
Starting program: /home/weeks/workSpace/codeofc/a.out 

Breakpoint 1, main () at main.c:6
6		int a=6, b=2;
(gdb) n
7		printf("%d+%d=%d\n", a, b, p_add(a,b));
(gdb) p a
$1 = 6
(gdb) p b
$2 = 2
(gdb) n
6+2=8
9		printf("hello beijing\n");
(gdb) n
hello beijing
10		return 0;
(gdb) n
11	}
(gdb) q
A debugging session is active.

	Inferior 1 [process 4363] will be killed.

Quit anyway? (y or n) y
weeks@weeks-virtual-machine:~/workSpace/codeofc$ gdb a.out 
GNU gdb (Ubuntu 7.11.1-0ubuntu1~16.5) 7.11.1
Copyright (C) 2016 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from a.out...done.
(gdb) l
1	#include <pmath.h>
2	#include <stdio.h>
3	//框架
4	int main(void)
5	{
6		int a=6, b=2;
7		printf("%d+%d=%d\n", a, b, p_add(a,b));
8		//組件
9		printf("hello beijing\n");
10		return 0;
(gdb) b main
Breakpoint 1 at 0x40056e: file main.c, line 6.
(gdb) r
Starting program: /home/weeks/workSpace/codeofc/a.out 

Breakpoint 1, main () at main.c:6
6		int a=6, b=2;
(gdb) n
7		printf("%d+%d=%d\n", a, b, p_add(a,b));
(gdb) s
p_add (a=6, b=2) at jingtai/add.c:5
5		return a+b;
(gdb) n
6	}
(gdb) n
6+2=8
main () at main.c:9
9		printf("hello beijing\n");
(gdb) n
hello beijing
10		return 0;
(gdb) n
11	}
(gdb) q
A debugging session is active.

	Inferior 1 [process 4380] will be killed.

Quit anyway? (y or n) y

四、环境变量的初识

每个进程都有自己的环境变量
程序和进程的区别:程序是指令的集合,静态的,存储在计算机硬盘上的;进程是程序运行的实例,程序运行一次产生一个进程。

程序在执行的过程中需要和操作系统打交道,需要操作系统提供一些资源。通过一种变量来传递这种资源,这样的变量就是环境变量。
???
以bash进程的环境变量为例
如何查看bash进程的环境变量?命令env
USER=weeks
环境变量的格式:name=value
=两边绝不能出现空格

如何读出环境变量的值? 命令echo $变量名
echo $USER
在这里插入图片描述
如何给一个变量设置初值?命令:name=value
自定义的变量是进程的私有变量
在这里插入图片描述
如何将自定义变量转换成环境变量?命令:export namename是自定义变量的名字

weeks@weeks-virtual-machine:~/workSpace/codeofc$ export caption
weeks@weeks-virtual-machine:~/workSpace/codeofc$ env
XDG_VTNR=7
LC_PAPER=zh_CN.UTF-8
LC_ADDRESS=zh_CN.UTF-8
XDG_SESSION_ID=c2
XDG_GREETER_DATA_DIR=/var/lib/lightdm-data/weeks
LC_MONETARY=zh_CN.UTF-8
CLUTTER_IM_MODULE=xim
GPG_AGENT_INFO=/home/weeks/.gnupg/S.gpg-agent:0:1
TERM=xterm-256color
VTE_VERSION=4205
SHELL=/bin/bash
QT_LINUX_ACCESSIBILITY_ALWAYS_ON=1
WINDOWID=58720266
LC_NUMERIC=zh_CN.UTF-8
OLDPWD=/home/weeks/workSpace/codeofc/jingtai
UPSTART_SESSION=unix:abstract=/com/ubuntu/upstart-session/1000/2031
GNOME_KEYRING_CONTROL=
GTK_MODULES=gail:atk-bridge:unity-gtk-module
USER=weeks
LS_COLORS=rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:mi=00:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arc=01;31:*.arj=01;31:*.taz=01;31:*.lha=01;31:*.lz4=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.tzo=01;31:*.t7z=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.dz=01;31:*.gz=01;31:*.lrz=01;31:*.lz=01;31:*.lzo=01;31:*.xz=01;31:*.bz2=01;31:*.bz=01;31:*.tbz=01;31:*.tbz2=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.war=01;31:*.ear=01;31:*.sar=01;31:*.rar=01;31:*.alz=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.cab=01;31:*.jpg=01;35:*.jpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.webm=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=00;36:*.au=00;36:*.flac=00;36:*.m4a=00;36:*.mid=00;36:*.midi=00;36:*.mka=00;36:*.mp3=00;36:*.mpc=00;36:*.ogg=00;36:*.ra=00;36:*.wav=00;36:*.oga=00;36:*.opus=00;36:*.spx=00;36:*.xspf=00;36:
LC_TELEPHONE=zh_CN.UTF-8
QT_ACCESSIBILITY=1
XDG_SESSION_PATH=/org/freedesktop/DisplayManager/Session0
XDG_SEAT_PATH=/org/freedesktop/DisplayManager/Seat0
SSH_AUTH_SOCK=/run/user/1000/keyring/ssh
DEFAULTS_PATH=/usr/share/gconf/ubuntu.default.path
XDG_CONFIG_DIRS=/etc/xdg/xdg-ubuntu:/usr/share/upstart/xdg:/etc/xdg
DESKTOP_SESSION=ubuntu
PATH=/home/weeks/bin:/home/weeks/.local/bin:/opt/Qt5.12.6/5.12.6/gcc_64/bin:/opt/Qt5.12.6/Tools/QtCreator/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
QT_IM_MODULE=fcitx
QT_QPA_PLATFORMTHEME=appmenu-qt5
LC_IDENTIFICATION=zh_CN.UTF-8
XDG_SESSION_TYPE=x11
PWD=/home/weeks/workSpace/codeofc
JOB=gnome-session
XMODIFIERS=@im=fcitx
GNOME_KEYRING_PID=
LANG=en_US.UTF-8
GDM_LANG=en_US
MANDATORY_PATH=/usr/share/gconf/ubuntu.mandatory.path
LC_MEASUREMENT=zh_CN.UTF-8
COMPIZ_CONFIG_PROFILE=ubuntu
IM_CONFIG_PHASE=1
GDMSESSION=ubuntu
SESSIONTYPE=gnome-session
GTK2_MODULES=overlay-scrollbar
SHLVL=1
HOME=/home/weeks
XDG_SEAT=seat0
LANGUAGE=en_US
GNOME_DESKTOP_SESSION_ID=this-is-deprecated
UPSTART_INSTANCE=
UPSTART_EVENTS=started starting
XDG_SESSION_DESKTOP=ubuntu
LOGNAME=weeks
DBUS_SESSION_BUS_ADDRESS=unix:abstract=/tmp/dbus-9cBe2KS6oy
XDG_DATA_DIRS=/usr/share/ubuntu:/usr/share/gnome:/usr/local/share:/usr/share:/var/lib/snapd/desktop
QT4_IM_MODULE=fcitx
caption=beijing
LESSOPEN=| /usr/bin/lesspipe %s
INSTANCE=Unity
UPSTART_JOB=unity-settings-daemon
XDG_RUNTIME_DIR=/run/user/1000
DISPLAY=:0
XDG_CURRENT_DESKTOP=Unity
GTK_IM_MODULE=fcitx
LESSCLOSE=/usr/bin/lesspipe %s %s
LC_TIME=zh_CN.UTF-8
LC_NAME=zh_CN.UTF-8
XAUTHORITY=/home/weeks/.Xauthority
_=/usr/bin/env

bash下两个特殊的环境变量

  • PS1:指定bash的提示符
    PS1=‘\W$’
    在这里插入图片描述
    bash启动的时候执行一个脚本程序,bash脚本程序:~/.bashrc,一般情况下会在这个文件中设置当前bash的环境变量
  • PATH:环境变量
    先看看PATH环境变量的值
    了解环境变量的值的意义:由冒号分割的多条路径。这些路径是什么意思?
codeofc$echo $PATH
/home/weeks/bin:/home/weeks/.local/bin:/opt/Qt5.12.6/5.12.6/gcc_64/bin:/opt/Qt5.12.6/Tools/QtCreator/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin

在PATH环境变量加入PATH中:PATH=$PATH:.。(严格区分大小写)
在这里插入图片描述

总结

一、大型软件的组织
  • 头文件的编写和使用
  • 框架和组件
  • 接口
  • 静态链接
  • 运行时文件
  • nm命令的使用
  • 编译的基本单位是源文件
  • C语言是由函数组成的
  • main函数和其他函数一样
二、静态库文件的制作和使用
  • 制作和使用的步骤
  • 头文件的包含<>/“”
  • gcc的参数(-E -S -c -L -l -I -o)
三、gdb调试工具的使用
  • 调试信息
四、环境变量
  • PS1
  • PATH
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值