1、选择题
1.1、若有定义语句:int a[3][6]; ,按在内存中的存放顺序,a 数组的第10个元素是 B
A)a[0][4] B) a[1][3] C)a[0][3] D)a[1][4]
解析:二维数组在内存中是以行优先的方式存放的。这意味着首先填充第一行的所有元素,然后是第二行,依此类推。第10个位置是 a[1][3]
1.2、有数组 int a[5] = {10,20,30,40,50}, 以下表达式编译错误是 B 。
A) a ++ ;
B) a[5] = 20 ;
C) a + 20 ;
D) (a-3, a[3]) ;
解析:数组的索引从0开始,所以一个大小为5的数组的有效索引范围是0到4。尝试访问或修改 a[5]
,属于越界访问,会导致编译错误或运行时错误。
1.3、以下错误的定义语句是 D
A)int x[][3] = {{0},{1},{1,2,3}};
B)int x[4][3] = {{1,2,3},{1,2,3},{1,2,3},{1,2,3}};
C)int x[4][] = {{1,2,3},{1,2,3},{1,2,3},{1,2,3}};
D)int x[][3] = {1,2,3,4};
解析:为x
提供了第二维的大小为3,但没有提供第一维的大小。但在初始化时,提供了4个元素,这意味着试图将一个一维数组初始化为一个二维数组。这是不合法的。
1.4、设int i,x[3][3]={1,2,3,4,5,6,7,8,9};则下面语句
for(i=0;i<3;i++)
printf(″%d, ″,x[i][2-i]);
的输出结果是 D
A)1, 4, 7 B)1, 5, 9 C)3, 6, 9 D)3, 5, 7
解析:当i=0
时,x[i][2-i]
就是x[0][2-0]
,即x[0][2]
,输出3
。当i=1
时,x[i][2-i]
就是x[1][2-1]
,即x[1][1]
,输出5
。当i=2
时,x[i][2-i]
就是x[2][2-2]
,即x[2][0]
,输出7。
所以,输出的结果是3,5,7
。
1.5、表达式“sizeof(int [1][2])/sizeof(int)”的值为 A 。
A) 2 B) 3 C) 4 D) 5
解析:sizeof(int[1][2])
获取的是一个1x2的整数数组的大小。在一个典型的32位或64位系统中,一个int
的大小通常是4字节。因此,1x2的整数数组的大小将是2*4=8字节。sizeof(int)
获取的是单个int
的大小,通常是4字节。所以,表达式 sizeof(int[1][2])/sizeof(int)
的值将是8/4=2。
1.6有以下程序
#include main()
{ char s[]="012xy\07s34f4w2";
int i,n=0;
for(i=0;s[i]!=0;i++)
if(s[i]>='0'&&s[i]<='9')
n++;
printf("%d\n",n);
}
程序运行后的输出结果是 C
A)0 B)3 C)7 D)8
解析:字符串中的 \07
是一个八进制转义序列,它代表一个 ASCII 值为 7 的字符,接下来遍历字符串 s
,并统计其中数字字符('0' 到 '9')的数量。字符串中的数字字符有:'0', '1', '2', '3', '4', '3', '4'。一共有 7 个。
因此,程序运行后的输出结果是 7。
1.7、有以下程序
#include
main( )
{ char s[ ]=”wstuv”; printf(“%c\n”,*s+2);
}
程序运行后的输出结果是 C
A)t B) tuv C)y D)出错
解析:*s
是指向字符串第一个字符 'w' 的指针。表达式 *s + 2
将 'w'(其 ASCII 值是 119)加上 2,得到 121,这是字符 'y' 的 ASCII 值。因此,printf("%c\n", *s + 2);
会输出字符 'y'。
1.8 数组 int a[5] = {10, 20, 30, 40,50}, 有以下语句,其输出 C
printf(“%d\n”, *(&a +1) );
A) 20 B) 30 C) 随机值 D)编译报错
解析:&a+1
意味着将指向数组的指针向前移动一个数组的大小,而不是移动一个整数的大小。在大多数系统上,一个整数的大小是4字节,而整个数组a
的大小是5个整数,即20字节。因此,&a + 1
实际上会跳过整个数组,指向数组后面的内存位置.*(&a+1)
是解引用这个指针,即访问这个指针指向的内存位置的值。由于这个指针指向的是数组a
后面的内存位置,这个内存位置的值是不确定的,可能是之前存储的数据,也可能是未初始化的内存。因此,这个操作是不安全的,并且会导致未定义的行为。所以是个随机值
1.9 有以下程序
# include
int main()
{ int s[12]={1,2,3,4,4,3,2,1,1,1,2,3}, c[5]={0,0,0,0,0}, i ;
for(i=0;i<12;i++) c[s[i]]++ ;
for(i=1;i<5;i++) printf(“%d,”,c[i]); printf(“\n”);
}
输出是 A
A) 4 ,3, 3, 2 B) 2 , 3, 4, 4
C) 1, 2, 3 ,4 D ) 4, 4, 2 ,3
解析:程序的主要目的是统计数组 s
中每个元素出现的次数,并将统计结果保存在数组 c
中。通过第一个 for
循环,程序遍历数组 s
中的每个元素,并使用该元素作为索引来增加数组 c
中相应位置的值。这样,c[i]
的值就会表示 s
中 i
出现的次数。因此,输出是:4, 3, 3, 2。
1.10 有数组 int a[3][4] = {10,20,30,40,50,60,70,80,90,100,110,120},执行以下语句输出的是 D
printf(“%d\n”, *(*a+2) + 3 );
A) 语句有错 B) 120 C) 30 D) 33
解析:*(*a+2)
是一个复合的解引用和指针运算。首先,*a
得到的是a[0]
的地址,这是一个指向4个整数的数组的指针。然后,*a+2
将这个地址向前移动2个整数的大小。这样,*a+2
现在指向a[0][2]
,即a
数组的第0行第2列的元素。最后,*(*a+2)
是对这个地址进行解引用,得到该地址处的整数值,即a[0][2]
的值。现在,我们要加上3,所以最终结果是a[0][2]
的值加3。a[0][2]
的值是30(从数组初始化列表中可以看到),所以30+3
等于33。因此printf(“%d\n”,*(*a+2)+3);
将输出33。
2、填空题
2.1、有以下程序
#include
main( )
{ int i,n[ ]={0,0,0,0,0};
for(i=1;i<=4;i++)
{n[i]=n[i-1]*3+1;
printf(“%d”,n[i]);}
}
程序运行后输出结果是 1 4 13 40
解析:根据初始条件,n[0]
是0,所以:当i=1
时,n[1]=n[0]*3+1=0*3+1=1
。当i=2
时,n[2]=n[1]*3+1=1*3+1=4
。当i=3
时,n[3]=n[2]*3+1=4*3+1=13
。当i=4
时,n[4]=n[3]*3+1=13*3+1=40
。因此,程序运行后的输出结果是:1 4 13 40
。
2.2、执行以下程序的输出结果是 3715 .
#include
int main()
{ int i,n[4]={1,0,0,0};
for(i=1;i<=3;i++)
{ n[i]=n[i-1]*2+1; printf("%d",n[i]); }
}
解析:当i=1
时,n[1]=n[0]*2+1=1*2+1=3
,然后打印3
。当i=2
时,n[2]=n[1]*2+1=3*2+1=7
,然后打印7
。当i=3
时,n[3]=n[2]*2+1=7*2+1=15
,然后打印15
。因此,程序的输出结果是:3715
。
2.3、下面程序运行的结果为 358 。
main()
{
int x[5],i;
x[0] = 1;x[1] = 2;
for(i = 2;i<5;i++) x[i] = x[i-1] + x[i-2];
for(i = 2;i<5;i++) printf(“%d”,x[i]);
}
解析:斐波那契数列的递推关系式x[i]=x[i-1]+x[i-2],x[0]=1
和x[1]=2
,接下来的斐波那契数列值将是:x[2]=x[1]+x[0]=2+1=3,x[3]=x[2]+x[1]=3+2=5,x[4]=x[3]+x[2]=5+3=8
因此,程序运行的结果是:358
2.4、有以下程序
#include
int main()
{
int arr[] = {1,3,5,7,2,4,6,8}, i, start ;
scanf(“%d”, &start);
for(i=0,i<7,i+=2)
printf(“%d”,arr[(start+i)%5]);
}
若在程序运行时输入整数 10 <回车>,则输出结果为 5 2 6 1
解析:循环开始,i
初始化为0
。计算(start+i)%8
,即(10+0)%8
,得到2
。打印arr[2]
,即5
。i
增加2
,变成2
。计算(start+i)%8
,即(10+2)%8
,得到4
。打印arr[4]
,即2
。i
再增加2
,变成4
。计算(start+i)%8
,即(10+4)%8
,得到6
。打印arr[6]
,即6
。i
再增加2
,变成6
。计算(start+i)%8
,即(10+6)%8
,得到0
。打印arr[0]
,即1
。i
再增加2
,变成8
。由于i<7
的条件不再满足,循环结束。因此,输出结果为:5 2 6 1
。
2.5下面程序运行的结果为 5 4 8 2 0 。
#include "stdio.h"
main()
{ int i,j,a[]={0,2,8,4,5};
printf("\n");
for(i=1;i<=5;i++)
{ j=5-i;
printf("%2d",a[j]);
}
}
解析:当i=1
时,j=5-1=4
,打印a[4]
,即5
。当i = 2
时,j=5-2=3
,打印a[3]
,即4
。当i=3
时j=5-3=2
,打印a[2]
,即8
。当i=4
时,j=5-4=1
,打印a[1]
,即2
。当i=5
时,j=5-5=0
,打印a[0]
,即0
。所以,程序运行的结果为:5 4 8 2 0
2.6有以下程序
#include
int main()
{ int n[2],i,j;
for(i=0;i<2;i++) n[i]=0; for(i=0;i<2;i++)
for(j=0;j<2;j++) n[j]=n[i]+1;
printf(“%d\n”,n[1]);
}
程序运行后的输出结果是 2
解析:当i=0
时,n[0]
和n[1]
都会被设置为0+1=1
。当 i=1
时,n[0]
和n[1]
都会被设置为1+1=2
。因此,在第二个循环结束后,数组 n
的内容将是 {2, 2}
。最后,程序打印数组 n
的第二个元素,即 n[1]
,其值为 2。
3、编程题
3.1、 一个班10个学生的成绩,存放在一个一维数组中,要求找出其中成绩最高的学生的成绩和该生的序号。试编程。(试着用下标法和地址法两种方法表示数组)
#include
#include
#include
using namespace std;
int main()
{
array score;
array::iterator iter; //定义了一个迭代器
for(iter=score.begin();iter!=score.end();iter++)//begin()第一个元素的地址 end()表示最后一个元素的下一个元素的地址
{
cin >> *iter;//循环输入学生成绩
}
//使用下标法
int index=0;
int hscore=score[0];
for(int i=1;i<10;++i)
{
if(score[i]>hscore)
{
hscore=score[i];
index=i;
}
}
cout << "最高成绩(下标法): " << hscore << ", 学生序号: " << index << endl;
//使用地址法
int *hscorep=&score[0];
for (int *ptr=score.begin();ptr!=score.end();++ptr)
{
if (*ptr>*hscorep)
{
hscorep=ptr;
}
}
int hindex=hscorep-score.begin();
cout << "最高成绩(地址法): " << *hscorep << ", 学生序号: " << hindex << endl;
return 0;
}
3.2、有5个学生上4门课程,要求输入全部学生的各门课程成绩,然后输出各门课程的平均成绩,并按照各个学生的平均成绩排序(成绩最高的学生排在数组最前面,最低学生排在数组最后面的行) (试着用下标法和地址法两种方法表示数组)。
#include
#include
#include
using namespace std;
class Student
{
public:
double scores[4];//存储学生的四门课程成绩
double avgScore;//存储学生的平均成绩
};
bool cmpscore(const Student &a, const Student &b)
{
return a.avgScore>b.avgScore;//降序排序
}
int main()
{
const int stu=5;
const int course=4;
double scores[stu][course];
// 输入学生的成绩
for(int i=0;i> scores[i][j];
}
}
// 使用下标法计算每门课程的平均成绩
vector courseavg(course, 0.0);
for(int j=0;j students(stu);
for(int i=0;i
结果: