gcc -g main.c -o main.out
才可以被gdb调试
gdb ./main.out
l
列出源代码break 12
设置断点start
开始单步调试p a
打印 a 变量n
回车nexts
step 单步 ,跳函数bt
查看函数堆栈f 1
切换到堆栈132位cpu 最大内存只有4G
32位cpu地址总线是32位,寻址空间是32位,给内存的编号只能编到32个二进制位, 2^32 = 4GB
64位cpu 可以管理内存 ..PB ..PE
操作系统认为 64位下 前48位(0x7fffffffffffffff
)给用户使用就足够,以上交给操作系统
栈 ,记录执行过程中的状态,执行到哪里,变量如何。 变量的本质就是内存。指针的本质是保存内存的地址。
全局变量,静态数据,放在数据段中。 全局变量永远保存在一个地方全局特有 静态变量属于每个函数特有的,对于相应的函数来说存在于一个地方。 但都不会压入栈中。
int 变量 32 位 4个字节
64位操作系统 ,指针 8个字节
gcc 编译器会对内存分配做优化,把同类型变量放在一起,指针运算会更快。
最先分配的栈,地址最大,从顶部向下分配,一般main函数最大
函数指针
已经知道地址,取变量
pquardrate
是一个地址
*pquardrate
解除引用,取存在地址处的值
如果这个指针指向的是栈内存、数据段内存,会取数据。
如果指向的是代码段,会取代码块。
(*pquardrate)
表示函数代码块整体
函数内部的数组,存到栈中,从小到大连续排放
指针的加减 按照指针类型加减
int *p
每次加减4个字节
指针偏移运算效率非常高
p+=3
表示把指针偏移三格,移动12个字节,
p[3]
和p+=3
效果一样,但 p+=3
改变了指针 p 的值,p[3]
只是做了偏移。通常
数组(指针常量)本身就是指针,都可以通过[]做偏移,但是不能改变: array += 3
不可以;
字符串数组 也是指针
str3 本身就是地址,直接传到scanf() str2 是一个指向字符串的指针,其内容是“word”这个字符串所在的地址,可能在数据段代码段,很小,不允许修改。 只可以在栈内存和堆内存中修改。
str
和str3
是连续分配的,如果输入超出,会写到其他变量中。