文章目录
Linux C语言 指针与内存
Linux C语言编程基本原理与实践
1.gcc是编译程序
2.make工具可以将大型的开发项目分成若干个模块,内部也是使用gcc
多文件操作
Linux中C语言程序编写的小操作
:sp 新建文件名 多vim文本编辑。
ctrl + w + ⬆️⬇️ 切换编辑的文本
:wqa 保存全部文件
gcc max.c hello.c -o hello.out 多文件编译,-o指定编译后文件名
如果预编译没有引用max.c,会有一个警告。最好的方式是在main函数的文件中声明max函数。
如果hello.c中写了max.c的声明,那么命令行不用写max.c,直接 gcc hello.c -o hi.out即可
gcc XXX.c 编译
gcc -c XXX.c编译(如果没有main函数,需要加-c来编译)
可以分开编译,这样可以节省时间
gcc XX1.c -o XX1.o
gcc XX1.o XXX.c 把已经编译的.o文件与XXX.c连接后编译
已编译成.o文件,为了避免需要知道.o文件的细节时,不能查看.o文件,可以编写一个.h头文件来描述.o文件的细节(函数声明),然后在main函数文件中预编译写入头文件。
Makefile编写
格式如下(自顶向下):
#注释
可执行文件:来源文件族
tab键 gcc 来源文件族 -o 可执行文件名
已编译文件:来源文件
tab键 gcc -c 来源文件
编写完成后,通过make命令执行
相当于自顶向下的写编译的过程,先写文件及其来源,后写gcc命令。如果已经编译过的文件,再次执行Makefile时会跳过,节省了时间。
main函数详解
1.执行一个程序后,命令行echo $?
返回上一个程序执行的return值。如果运行错误会返回一串错误码。
2.int main(int agrc,char* agrv[])
agrc :argument count
agrv :agrument vector
main后面的形参用于和操作系统进行交互。
如下:
标准输入输出流,错误流
stdin:标准输入流文件,默认键盘
stdout:标准输出流文件,默认电脑终端
stderr:标准错误流文件
printf相当于fprintf的特殊形式
以下两个命令结果一样
fprintf(stdout,“hello”);
printf(“hello”);
以下两命令结果一样
fscanf(stdin,"%d",&a);
scanf("%d",&a);
错误流输出
fprintf(stderr,“error happen.”);
文件内容输入和输出
>> 追加写出
> 覆盖写出
< 输入
0 表示标准输入流写入
1 表示标准输出流写出
2 表示标准错误流写出
使用gdb调试
参考链接
⚠️:要用gdb来调试的程序,必须用gcc -g .c文件 -o .out执行文件
来编译,且必须能找到源代码。
回车
继续执行上一个操作
启动gdb
gdb ./执行文件.out
gdb -q 执行文件
不打印版本信息,界面简洁
start
开始调试
显示当前断点位置(hash值)
查看
list
或l
显示源代码list,默认显示10行,回车可继续显示
print 参数
或p 参数
print显示参数的值
whatis 参数
显示参数类型
x/3d 地址
从该地址开始以十进制(d)显示3个数
运行程序
r
run,运行程序直到结束或遇到断点。
设置断点
break 行号
:简写b 行号
在某行设置断点
info breakpoints
显示断点信息
Num
断点编号
Disp
断点执行一次后是否有效。kep / dis
Enb
当前断点是否有效,y or n
Address
内存地址
What
位置
单步执行
step
简写s
进入函数
显示这个change函数,传入的a和b的值。(是地址值)
continue
或c
继续执行程序,直到下一个断点或结束
next
或n
单步执行,遇到函数会直接执行,但不进入。
函数堆栈
bt
查看函数堆栈
f 数字
切换函数
退出gdb调试
quit
或q
退出gdb调试
其他操作
until
运行程序到退出循环体
until 行号
运行至某行
finish
运行程序直到档案函数完成并返回,并打印函数返回时的堆栈地址和返回值及参数值等信息
内存管理
32bit主机的电脑最大只能用4G的内存。因为它最多给内存编地址到32位。
应用程序是由操作系统来调用的。操作系统中内存的最小访问单位是字节,即8bit。
64位的主机,一般低于48位(低于0xffffffffffff)的地址给应用程序用,高于48的地址给操作系统用。这样内存隔开,好处:
1.操作系统的内存不用被大量占用;
2.避免机器卡住、死机等状态;
3.可通过操作系统把应用程序关闭;
4.使得操作系统更安全。
代码编译执行时,状态(包括正在执行哪个函数,到多少行,中间的一些变量等)会被保存在栈中。
指针在64位的系统中,占8个字节。
【问题】:
p:跟老师演示的不一样,老师上面后面三个应该是array的地址,但是我的这里是其他地址,再往后就是array的地址了。打到6,7,8位置才是想要的值。
- 问题:为什么b地址会在i地址后面???