前言:
现时大家对“c语言数组的习题”大概比较重视,朋友们都需要学习一些“c语言数组的习题”的相关知识。那么小编在网摘上搜集了一些有关“c语言数组的习题””的相关知识,希望兄弟们能喜欢,兄弟们快快来了解一下吧!01
绘制调用栈
int f1(int k, int m){ int y; y = k + m; return y;}void f2(void){ int a = 83; int c = -74; c = f1(a, c); //其他代码}
绘制调用栈:
1、在f1被调用之前.
2、当程序完成了第4行.
3、当程序完成了f1, 且最顶部的栈帧出栈.
解答:
1、在f1被调用之前. f2中初始化a, c后调用的, 所以如下:
栈帧
标志符
地址
值
f2
c
101
-74
a
100(假定100开始)
83
2、当程序完成了第4行. f1是嵌套在f2中的, 如下:
栈帧
标志符
地址
值
f1
y
106
9
m
105
-74
k
104
83
值地址
103
101
返回位置
102
13行
f2
c
101
-74
a
100
83
3、当程序完成了f1, 且最顶部的栈帧出栈. 其实就是上面的程序执行完.
栈帧
标志符
地址
值
f2
c
101
9
a
100
83
02
绘制调用栈2
void f1(int k, int m){ int y; y = k; k = m; m = y;}void f2(void){ int a = 83; int c = -74; f1(a, c); //一些代码}
绘制调用栈
1、当程序已经输入f1并完成了第4行. k和m的值是多少?
2、当程序完成了第6行, 且在f1的栈帧出栈之前. k和m的值是多少呢?
3、当程序完成了f1且f1的栈帧已经出栈时, a和c的值是多少呢?
解答:
1、当程序已经输入f1并完成了第4行. k和m的值是多少?
栈帧
标志符
地址
值
f1
y
105
83
m
104
-74
k
103
83
返回位置
102
第14行
f2
c
101
-74
a
100
83
2、当程序完成了第6行, 且在f1的栈帧出栈之前. k和m的值是多少呢?
栈帧
标志符
地址
值
f1
y
105
83
m
104
83
k
103
-74
返回位置
102
第14行
f2
c
101
-74
a
100
83
3、当程序完成了f1且f1的栈帧已经出栈时, a和c的值是多少呢?
a, c值是不变的.
栈帧
标志符
地址
值
f2
c
101
-74
a
100
83
03
三个问题
1、开发人员怎么才能控制一个变量的地址呢?
答曰: 无法控制.
2、如果相同的程序运行多次, 相同变量的地址会是相同的吗?
答曰: 可能是不同的.
3、一个数组元素的地址是连续的还是离散的?
答曰: 连续的.
04
在DDD(命令行调试程序)上检测调用栈
在linux中输入如下代码命名为p1.c:
#include <stdio.h>#include <stdlib.h>int g1(int a, int b){ int c = (a + b) * b; printf("g1: a = %d, b = %d, c = %d\n", a, b, c); return c;}int g2(int a, int b){ int c = g1(a + 3, b - 11); printf("g2: a = %d, b = %d, c = %d\n", a, b, c); return c - b;}int main(int argc, char **argv){ int a = 5; int b = 17; int c = g2(a - 1, b * 2); printf("main: a = %d, b = %d, c = %d\n", a, b, c); return EXIT_SUCCESS;}# 使用命令:gcc -g -Wall -Wshadow p1.c -o p1进行编译
-g 表示启用调试, -Wall和-Wshadow启用警告信息. -o表示编译完后的输出文件. 运行结果如下:
# ./p1g1: a = 7, b = 23, c = 690g2: a = 4, b = 34, c = 690main: a = 5, b = 17, c = 656
在命令行中输入 gdb p1进入调试模式
gdb p1GNU gdb (GDB) Red Hat Enterprise Linux 7.6.1-120.el7Copyright (C) 2013 Free Software Foundation, Inc.License GPLv3+: GNU GPL version 3 or later <;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-redhat-linux-gnu".For bug reporting instructions, please see:<;...Reading symbols from /data/Clang/p1...done.(gdb)
在g1和g2两个函数处设置断点:
(gdb) b g1Breakpoint 1 at 0x40052b: file p1.c, line 6.(gdb) b g2Breakpoint 2 at 0x400567: file p1.c, line 13.(gdb)
b g1表示在g1开始时设置断点, 当程序到达g1的第一行, 程序将停止. b g2同理.
运行run可以执行.
(gdb) runStarting program: /data/Clang/p1 Breakpoint 2, g2 (a=4, b=34) at p1.c:1313 int c = g1(a + 3, b - 11);Missing separate debuginfos, use: debuginfo-install glibc-2.17-292.el7.x86_64
在g2的断点处停止了. 设置多个断点, 程序将按照被执行的顺序停止在断点处. 不是按照它们被设置的顺序. 继续运行
(gdb) continueContinuing.Breakpoint 1, g1 (a=7, b=23) at p1.c:66 int c = (a + b) * b;
这回在g1的断点处了, 执行"栈回溯”命令:
(gdb) bt#0 g1 (a=7, b=23) at p1.c:6#1 0x000000000040057c in g2 (a=4, b=34) at p1.c:13#2 0x00000000004005d7 in main (argc=1, argv=0x7fffffffe618) at p1.c:22
每一行的起始显示了调用栈的栈帧(0, 1, 2), 与函数g1, g2和main函数相对应. 使用f命令可以看到不同的栈帧:
(gdb) f#0 g1 (a=7, b=23) at p1.c:66 int c = (a + b) * b;
还有一些其他命令, 可以自己摸索, 这里就不阐述了.
标签: #c语言数组的习题