1,以下程序的输出结果是()
#include <stdio.h>
int main()
{
char a[10] = {'1', '2', '3', '4', '5', '6', '7', '8', '9', 0}, *p;
int i;
i = 8;
p = a + i;
printf("%s\n", p - 3);
}
A 6
B 6789
C ‘6’
D 789
解析 :B, p = a + i, 那么 p = &a[8]; p-3 ,那么p = &a[5], 输出格式为 %s,遇到‘\0’停止,‘\0’的值实际上就是0
以下程序的输出结果是()
#include <iostream.h>
int main()
{
int x=3,y=3;
switch(x%2)
{
case 1:
switch (y)
{
case 0:
cout<<"first";
case 1:
cout<<"second";
break;
default:
cout<<"hello";
}
case 2:
cout<<"third";
}
return 0;
}
A second third
B hello
C first second
D hellothird
解析 : D x % 3 的结果为1, 进入case1,y 的值为3,没有值,进入了默认default,打印了"hello", 然后指向完case1后,由于没有break 语句,所以继续向下执行case2,打印“third”
3,以下能对二维数组a进行正确初始化的语句是()
A int ta[2][]={{0,1,2},{3,4,5}};
B int ta[][3]={{0,1,2},{3,4,5}};
C int ta[2][4]={{0,1,2},{3,4},{5}};
D int ta[][3]={{0,2},{},{3,4,5}};
解析: B, 行标可以省略, 列表是不能省略的。这个可以这样思考, 二维数组其实是由许多个一维数组构成的,你觉得是一维数组的个数重要,还是一维数组中的元素个数重要呢? 显然是后者。 如果行标固定,列表不固定,那每个一维数组的元素都可以胡乱添加,只要满足行标就行了, 而列表固定,可以添加行数,但还是满足行列的要求的。C选项明显错误2行,它却给了3行。 而D选项用法没错,但是第一个一维数组 0和2之间给力 两个逗号。
4,能把函数处理结果的二个数据返回给主调函数,在下面的方法中不正确的是()
A return这二个数
B 形参用数组
C 形参用二个指针
D 用二个全局变量
解析 : A, C/C++的函数只能返回1个数。 B的话用数组实际上是数组元素的起始地址,也是个指针,你知道别人的地址,修改返回当然可以了。
5,int *p[4] 与选择项中的() 等价
A int p[4]
B int *p
C int *(p[4])
D int (*p)[4]
解析 : C,[ ]的优先级非常高,所以p和[ ]先结合, 所以是个数组,然后每个元素是指针int*
6, 设变量已正确定义,以下不能统计出一行中输入字符个数(不包含回车符)的程序段是
A n=0;while(ch=getchar()!=‘\n’)n++;
B n=0;while(getchar()!=‘\n’)n++;
C for(n=0;getchar()!=‘\n’;n++);
D n=0;for(ch=getchar();ch!=‘\n’;n++);
解析 : D, 肯定选择D, 因为for(表达式1;;) , 表达式1称为初始化,只会执行一次
7,以下代码
char *ptr;
char myString[] = “abcdefg”;
ptr = myString;
ptr += 5;
代码执行之后ptr指向的内容是?
A Compiler error
B fg
C efg
D defg
解析 : B , ptr = ptr + 5, 指向下标为5的地址
8,下面3段程序代码的效果一样吗()
int b;
(1)const int *a = &b;
(2)int const *a = &b;
(3)int *const a = &b;
A (2)=(3)
B (1)=(3)
C (1)=(2)
D 都不一样
解析 : C, 其实const作用在哪, 完全取决于放在 * 的前面 还是 * 的后面,放在*的前面,修饰的就是 *p, 防止 *的后面修饰就是p
9, 32位系统中,定义int **a[3][4],则变量占用内存空间为()
A 4
B 48
C 192
D 12
解析 : B, 32位系统下指针是4个字节, 而64位系统下是8个字节。 3 * 4 * 4 = 48
10,假设在一个 32 位 little endian 的机器上运行下面的程序,结果是多少?
#include <stdio.h>
int main()
{
long long a = 1, b = 2, c = 3;
printf("%d %d %d\n", a, b, c);
return 0;
}
解析 : B,32位小端 , 大小端的区别,
大端 : 低地址存放的是数据的高位, 高地址存放的是数据的低位。
小端 : 低地址存放的是数据的低位, 高地址存放的是数据的高位。
可以认为cpu每次都是从低位数据开始读的,long long 是8个字节, 1 的2进制数据 01 00 00 00 00 00 00 00
而%d只读4个字节,当读取a的时候,先把a加入到缓存中,所以第一次读取为 01 00 00 00 也就是1,
第二个%d也读4个字节, 也就是 00 00 00 00 , 第三个%d先将b加入缓存是 02 00 00 00 00 00 00 00
然后第三个%d读的就是 02 00 00 00
有以下程序
#include<iostream>
#include<cstdio>
using namespace std;
int main()
{
int m=0123, n=123;
printf("%o %o\n", m, n);
return 0;
}
以下程序的输出结果是:()
A 0123 0173
B 0123 173
C 123 173
D 173 173
解析: C, 0开头的是8进制数据,把123转换成8进制数据就是173。
12, 以下哪个选项一定可以将flag的第二个bit置0()
A flag&=~2
B flag|=2
C flag^=2
D flag>>=2
解析 : A 2的比特位是 0000 0000 0000 0000 0000 0000 0000 0010 取反 -->1111 1111 1111 1111 1111 1111 1111 1101, 然后的话0按位与0或1都是0.
13,请声明一个指针,其所指向的内存地址不能改变,但内存中的值可以被改变
A const int const *x = &y;
B int * const x = &y;
C const int *x = &y;
D int const *x = &y;
E const int * const x = &y;
解析 : B, const 放在*的前面, 修饰的是 *p, 表示指向的值不能改变, 放在 *的后面, 修饰的是指针,则指针不能修改指向的地址。
14以下C语言指令:
int a[5] = {1,3,5,7,9};
int p = (int )(&a+1);
printf(“%d,%d”,(a+1),(p-1));
运行的结果是 ?
A 2,1
B 3,1
C 3,9
D 运行时崩溃
解析 : C, &a —> 取地址数组名取出的是整个数组的地址, 加1跳过整个数组
15, 二维数组X按行顺序存储,其中每个元素占1个存储单元。若X[4][4]的存储地址为Oxf8b82140,X[9][9]的存
储地址为Oxf8b8221c,则X[7][7]的存储地址为()。
A Oxf8b821c4
B Oxf8b821a6
C Oxf8b82198
D Oxf8b821c0
解析 :A, 1个存储单元,相当是一个字节,设每一行有n个元素,那x[9][9] - x[4][4]的地址差为 220, 那他们具体之间隔多少隔元素呢?
n - 4 + (9 - 4 - 1) * n + 9 = 220 , 算出 n 为43, 那x[4][4] 和x[7][7] 又隔多少隔元素呢 ? 43 - 4 + (7 - 4 - 1) * 43 + 7 = 132
132 = 16 ^ 0 * 4 + 16 ^1 * 8 也就是 0x84
最终结果是 : 0xf8b82140 + 0x84 = 0xf8b821c4
16,根据下面递归函数:调用函数Fun(2),返回值是多少()
int Fun(int n)
{
if(n==5)
return 2;
else
return 2*Fun(n+1);
}
A 2
B 4
C 8
D 16
解析 : D, 16。 递归函数展开 2 * 2 * 2 * 2 = 16
17,
以下程序的输出结果是:
#include <iostream>
using namespace std;
void func(char **m)
{
++m;
cout<<*m<<endl;
}
int main()
{
static char *a[]={"morning", "afternoon", "evening"};
char **p;
p=a;
func(p);
return 0;
}
A afternoon
B 字符o的起始地址
C 字符o
D 字符a的起始地址
解析 : A, 数组名a是数组的起始地址,数组的起始地址也是二级char** ,所以这里的m++就是向后走一个元素“morning”
18,
求函数返回值,输入x=9999
int func(int x)
{
int count=0;
while (x)
{
count++;
x=x&(x-1);//与运算
}
return count;
}
解析 : A, 其实这道题难解,基本上只能蒙, 虽然我们知道这个函数的功能是统计数的二进制位1的个数, 但是9999不用计算机很难知道。
19,
#include <stdio.h>
int cnt = 0;
int fib(int n)
{
cnt++;
if (n == 0)
return 1;
else if (n == 1)
return 2;
else
return fib(n - 1) + fib(n - 2);
}
void main()
{
fib(8);
printf("%d", cnt);
}
A 41
B 67
C 109
D 177
解析;B, 这个函数的功能是统计递归展开了多少次。可以自己画图数一下, 是67次, 基本上可以猜测预估一下, 从8到结尾2,基本上是6
可以理解位是2 ^ 6
20,在32位系统环境,编译选项为4字节对齐,那么sizeof(A)和sizeof(B)是()
struct A
{
int a;
short b;
int c;
char d;
};
struct B
{
int a;
short b;
char c;
int d;
};
A 16,16
B 13,12
C 16,12
D 11,16
解析 : C, 结构体内存对齐, 每一次的对齐位置与默认对齐数比较,取较小值,然后最后的大小是使用过的对齐数中最大的倍数。
A:4 + 2 + 2 + 4 + 1 + 3 = 16
B: 4 + 2 + 1 + 1 + 4 = 12
扩展问题 : 为什么要有结构体的内存对齐呢?
1, 为了访问数据方便, 因为cpu访问数据的时候, 如果访问没有对齐的数据可能要访问2次,而访问对齐的数据,只用访问一次
2, 可移植性,对于对齐的数据而言,拥有良好的跨平台性