您的位置:首页 > 编程语言

Unix高级编程:环境变量、静态库、动态库制作和使用、gdb调试工具

2017-01-14 21:34 288 查看
判断电脑大端小端 (内存地址默认从低地址到高地址)

方法 1. short var_a = 0x0001;char *var_p = &var_a;如果var_p是1,则为小端

方法 2. union{ short var_a; char var_p; }; 如果var_p是1,则为小端

学好C语言3句话:

1. 常量和变量

2. 运算符的优先级和结合性

3. 变量的内存空间。访问一个变量的时候,首先通过变量的名字找到变量的地址,然后根据变量的类型访问变量的内存空间

("运算符优先级表"&"ASCII码表"&"进程映射"&"编译过程"&"小工具,如gdb")

一、环境变量 ————"《鸟哥linux私房菜》"

程序在运行的时候,操作系统通过变量提供的环境。

查看环境变量:

"env" (命令行)

环境变量的格式:

环境变量的名字=环境变量的值

如:USER=tarena

注意:"=号左右两边不允许有空格"

读取环境变量的值:

$USER

读取环境变量的值 $环境变量名

将换将变量USER的值显示到屏幕上:

"echo $USER"

如:echo "$USER" 双引号读值; '$USER' 单引号强制显示命令行内容

"怎么去设置环境变量的值":

(1)name="zhangsan"  ("自定义变量")

echo $name (zhangsan显示到屏幕上)

自定义变量不能被子进程继承

环境变量可以被子进程继承

(2)export name="zhangsan" (export:导出)

将自定义变量转化为环境变量

(3)unset name (删除自定义环境变量name,同时也会删除其值)

常用的环境变量:

PATH (以 : 分隔开多个路径,命令行的命令都会在这里面下找)

export PATH=$PATH:.  ("环境变量中的末尾加上当前目录 . ")

"修改~/.bashrc文件"。(~ 当前用户的工作主目录)

为什么修改?"bash启动的时候,会优先执行这个文件"

~/.bashrc 是shell脚本文件

# (sharp) // 文件~/.bashrc里面的注释符,#号后面跟注释内容

! (bang)

. (dot)

补充:

CCNA 基础网络工程师认证

CCNP 高级网络工程师认证

CCIE 最高级网络工程师认证

"命令行提示符":环境变量PS1

PS1="\e[33;1m[\w]\e[0m\$: " //完整路径+路径变黄色

PS1='\W\$: ' //只显示当前路径

source ~/.bashrc //执行修改后的bashrc文件

"bash与source区别"

bash:sh与bash分别用自己的shell来跑文件

source:该命令可用 . (点)来代替,用于重新执行刚修改的初始化文件

"source、exec、sh区别"

source:在原进程中执行,不会fork(派生指令)子进程

exec:在原进程中执行,但是会同时终止原进程

sh:父进程会fork一个子进程,shell script在子进程中执行

二、静态库的制作和使用

静态库的命名:lib+库名.a

制作静态库:

1. 将源文件编译为目标文件 .o 

2. 将目标文件打包到静态库文件

3. 使用静态库文件编译链接,形成可执行文件

举例:  /*源代码参见tmath文件夹*/
tmath文件夹:add.c  mul.c  process.c  process.h  tmath.h

对应第 1 步:gcc -c *.c
tmath文件夹:add.c  add.o  mul.c  mul.o  process.c  process.h  
process.o  tmath.h

对应第 2 步:ar -r libtmath.a *.o  //打包,库名为tmath
ar: creating libtmath.a
tmath文件夹新增:libtmath.a

对应第 3 步:gcc test.c -Ltmath -ltmath

或者第 3 步:gcc test.c -Ltmath -ltmath -Itmath

(-I 指令的第3步在tmath文件的同级)

-L路径(指定了仓库的地址)

-l库名(指定了所要用到的仓库)

-I路径(将这个路径添加到文件包含的系统指定的路径中)

在编译的时候,发生了链接。这种链接成为静态链接。

这种库就是静态库,静态库里的函数在编译的时候被链接到可执行文件里

扩充:ar 命令的使用(man ar 查看记录/百度手机搜索)

1. ar -t libtmath.a //显示静态库中已包含的.o文件

2. ar -d //从库中删除指定的文件

3. ar -m //将指定的文件移动到库中

4. ar -p //将files参数中指定的文件的内容都写至标准输出

5. ar -q //将指定的文件添加到库的末尾

6. ar -r //如果指定的文件存在库中,则替换它

7. ar -s //无论ar命令是否修改了库内容都强制重新生成库符号表

8. ar -x //通过将指定的文件复制到当前目录来解压缩它们

三、动态库的制作和使用

动态库的命名:lib+库名.so

制作动态库:

1. 将所有的源文件编译成目标文件,在编译的时候需要加参数 -fPIC

2. 将所有的目标文件生成动态库文件

3. 使用动态库文件生成可执行文件

举例:

对应第 1 步:gcc -c -fPIC *.c //PIC可重定位的,与目标无关的

对应第 2 步:gcc -shared -o libtmath.so *.o

对应第 3 步:gcc test.c -Ltmath -ltmath -Itmath 

./a.out

./a.out: error while loading shared libraries: 

libtmath.so: cannot open shared object file: No such file or directory //加载器找不到库文件在哪

发生这个错误的原因是:.so动态库没有加载到内存

ldd命令的使用:

ldd 可执行文件 //【查看】可执行文件依赖的动态库文件

ldd a.out

加载器通过加载器的搜索路径:(可扩充)

1. LD_LIBRARY_PATH 指定加载器的搜索路径,是一个环境变量

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:tmath 

//增加路径,就告诉了加载器动态库在tmath文件夹里面,执行时就可加载

2. /usr/lib 或 /lib 即是编译器的默认路径,又是加载器的默认路径

sudo 使用的是超级用户的权限执行的(临时的,执行完就是普通用户了)

sudo mv libtmath.so /usr/lib/   //密码123456789

cd /usr/lib/

ls -l libtmath.so  //查看.so是否存在

cd ~ //返回用户目录

cd ~/jy/uc/1130/  //到这个目录下执行gcc,就使用了默认路径

gcc test.c -ltmath -Itmath //不需要找仓库地址-L,再执行a.out

"将tmath文件夹下的文件制作成和标C库一样的效果":

1. 将头文件移动到 /usr/include 文件夹下

sudo mv *.h /usr/include

2. 修改.c源文件的包含文件的双引号""为尖括号<>

3. 将add.c、mul.c、process.c制作成动态库文件libtmath.so

4. 将动态库文件libtmath.so移动到/usr/lib

5. 使用动态库编译链接test.c //gcc test.c -ltmath不需要-I指定路径

静态库和动态库的区别:

静态库,在可执行文件在编译的阶段就已经将函数的代码复制到可执行文件里面了,编译编译链接完成。//可执行文件就不依赖于静态库文件

动态库,在编译链接阶段,并没有将函数的代码复制到可执行文件里,在可执行文件加载的时候,才将链接实现。//延迟加载或延时加载,可执行文件依赖与动态库的存在而存在

在一个文件夹下,如果动态库和静态库文件同时存在,在编译链接的时候,"默认的采用动态链接库"。

如果想在编译链接的时候使用静态库,需要指定 -static 编译参数

gcc -static test.c -Ltmath -ltmath //设置使用静态库编译

四、gdb调试工具的使用 //调试运算步骤

1. 编译链接程序的时候,gcc的最后加入 -g 或 -ggdb 参数,说明生成的可执行文件包含调试信息,如:

gcc test.c tmath/add.c tmath/mul.c tmath/process.c -g

2. 用"gdb a.out"调试,gdb调试器的命令
"l" list,将程序的代码显示出来
"b" breakpoint,设置断点,格式:"b 行号/函数名"
"r" ran,运行
"p" print,打印变量的内容,格式:"p 变量名"
"n" next,执行下一条指令
"s" step,一步一步执行
"q" quit,退出调试
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  gdb 操作系统