1.
以下变量分配在BSS段的是()
| 1 2 3 4 5 6 7 | char s1[100]; int s2 = 0; static int s3 = 0; void main() { char s4[100]; } |
A,s1 B,s2 C,s3 D,s4
BSS段:通常是指用来存放程序中未初始化的全局变量的一块内存区域;
数据段:通常是指用来存放程序中 已初始化 的 全局变量 的一块内存区域,static意味着在数据段中存放变量;
代码段:通常是指用来存放 程序执行代码 的一块内存区域;
堆:存放进程运行中被动态分配的内存段,它的大小并不固定,可动态扩张或缩减,这一块在程序运行前就已经确定了;
栈:栈又称堆栈, 存放程序的 局部变量 (不包括static声明的变量)。除此以外,在函数被调用时,栈用来传递参数和返回值。
正确答案:A
2.
以下程序的输出结果为________________.
| 1 2 3 4 5 6 7 8 9 10 | #include #define ADD(x) x*x main( ) { int a=4,b=6,c=7,d=ADD(a+b)*c; printf("d=%d",d); } |
宏定义只是简单的文本替换,并不会进行运算的优先级。
#define ADD(x) x*x
int main( )
{
int a=4,b=6,c=7,d=ADD(a+b)*c;
printf("d=%d",d);
//ADD(a+b)*c=x*x*c=4+6*4+6*7=70;
}
.就是简单的替换
3.
| 1 2 3 4 5 6 7 | #include "stdio.h" int main() { int a = 8, b; b = a|1; b >>= 1; printf("%d,%dn", a, b); } |
上面的C程序段的输出为__________.
C语言中|是按位或的意思,a可以表示为00001000,1表示为00000001,因此b为00001001,>>表示右移一位,因此b为00000100,即为4
答案:8 4.
4.
在 32 位编译器上,设有定义
| 1 | char *str1 = "Hello", str2[] = "Hello"; |
则以下语句
| 1 | printf("%d %d", sizeof(str1), sizeof(str2)); |
的输出结果是____________.
解析:
这题非常有趣
所谓的有趣不是题目考核的sizeof的知识
而是两个字符串的存储位置是不同的
考虑如下示例代码:
| 1 2 | char *a = "Hello", b[] = "Hello"; printf("%p %pn",a, b); |
可得以下输出:
0x100000faa 0x7fff5fbff742
可见两者虽看似指向相同的数据
实际上却有着完全不同的内存表现
b所处的0x7fff5fbff742就是函数堆栈
所以当函数结束后这个字串就会被抛弃
事实上本着能省则省的原则
编译器不会去销毁它,只是让他留在内存中称为脏数据罢了
你无法对其寻址,并且这段内存随时可以被新的入栈数据覆盖
而a所处的0x100000faa是个全局的区域
让我们对题目中的代码反编译
可得到汇编代码
截取以下有效信息:
| 1 2 3 | .section __TEXT,__cstring,cstring_literals L_main.b: ## @main.b .asciz "Hello" |
可以看到a指向的字符串被保存在了__TEXT段的__cstring节
这个节的性质是用于存储cstring_literals也就是C语言的字符串字面值类型
这里的.asciz就是说明"Hello"是一个C语言的字符串字面值类型
其地址偏移则表示为标记L_main.b
汇编里就通过这个标记对"Hello"字串进行寻址
存储在__cstring中的字符串字面值可以复用
也就是说相同的指向"Hello"都指向L_main.b这个"Hello"
这样就提升了空间效率
5.
下面这段程序的输出是什么?
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | #include class A{ public: A(){ p(); } virtual void p(){ printf("A"); } virtual ~A(){ p(); } }; class B:public A{ public: B(){ p(); } void p(){ printf("B"); } ~B(){ p(); } }; int main(int, char**){ A* a = new B(); delete a; } |
解析:
构造函数和析构函数是无法实现多态性的。理由是:
1.构造函数中,先构造父类,再构造子类,父类构造函数中调用函数,此时子类还没有构造,怎么实现多态性?
2.析构函数中,先析构子类,再析构父类。当我们在一个类中执行析构函数时,它的派生类都已经析构了,自然无法实现多态性。
所以答案就是:ABBA



