PTA | 指针相关题目及解析
1-1
若有定义:int *p[3]
; 则以下叙述中正确的是( )。
A.定义了一个基类型为 int
的指针变量
p
,该变量具有3个指针
B.定义了一个指针数组
p
,该数组含有3个元素,每个元素都是基类型为 int
的指针
C.定义了一个名为 *p
的整型数组,该数组含有3个
int
类型元素
D.定义了一个可指向一维数组的指针变量 p
,所指一维数组应具有3个 int
类型元素
GPT
在 C 语言中,表达式 int *p[3];
的含义是:
p
是一个数组p
的每个元素都是一个指向int
类型的指针- 数组
p
有 3 个这样的元素
根据这个解释,我们可以分析给出的选项:
A. 这个选项错误地理解为 p
是一个指针,它指向了 3
个指针。实际上,p
是一个包含 3 个指针的数组。
B. 这是正确的描述。p
是一个数组,数组中每个元素都是指向
int
类型的指针,且数组有 3 个这样的元素。
C. 这个选项错误地将 p
解释为一个整型数组。实际上,p
是一个指针数组。
D. 这个选项错误地描述了 p
作为一个指向一维数组的指针,这并不正确。p
本身是一个数组,它的元素是指针。
因此,正确答案是 B:定义了一个指针数组 p,该数组含有3个元素,每个元素都是基类型为 int 的指针。
1-2
有说明:char *language[]={"FORTRAN","BASIC","PASCAL","JAVA","C"};
则表达式language[1]>language[3]
A.字符B
和字符J
B.字符串FORTRAN
和字符串PASCAL
C.字符F
和字符P
D.字符串BASIC
和字符串JAVA
GPT
在 C
语言中,char *language[]={"FORTRAN","BASIC","PASCAL","JAVA","C"};
定义了一个字符串数组,其中每个元素都是一个指向字符的指针。这些指针分别指向
"FORTRAN", "BASIC", "PASCAL", "JAVA", 和 "C" 这几个字符串。
当比较 language[1] > language[3]
时,实际上是比较字符串 "BASIC" 和 "JAVA"
在内存中的地址。这个比较的结果取决于字符串在内存中的存储位置,而这通常是由编译器和运行时环境决定的,无法确定比较的结果是真还是假。
但是,选项中没有关于内存地址的比较,而是关于字符或字符串的内容比较。因此,根据提供的选项:
- A: 字符 B 和字符 J — 这个选项错误,因为比较的不是单个字符。
- B: 字符串 FORTRAN 和字符串 PASCAL — 这个选项也错误,因为它们不是
language[1]
和language[3]
。 - C: 字符 F 和字符 P — 这个选项同样错误。
- D: 字符串 BASIC 和字符串 JAVA — 这是正确的描述,因为
language[1]
是 "BASIC",language[3]
是 "JAVA"。
所以,正确答案是 D:字符串 BASIC 和字符串 JAVA。但请注意,这里的比较是比较字符串地址,而不是比较字符串内容。
1-3
当调用函数时,实参是一个数组名,则向函数传送的是_____ 。
A.数组的长度
B.数组的首地址
C.数组每一个元素的地址
D.数组每个元素中的值
1-4
以下语句或语句组中,能正确进行字符串赋值的是( )
GPT
在 C 语言中,字符串赋值需要特别注意,因为字符串实际上是字符数组,且字符串字面量(如 "right!")在 C 中是字符数组的常量表示。我们逐个分析给出的选项:
A. char *p; *p="right!";
- 这是错误的。p
是一个未初始化的指针,直接对 *p
进行赋值是危险的,因为它可能指向任何地方。而且 "right!"
是一个字符串字面量(字符数组),不能直接赋值给
*p
(一个字符)。
B. char s[10]; s="right!";
- 这同样是错误的。虽然
s
是一个字符数组,可以存储字符串,但不能直接使用
=
运算符将一个字符串字面量赋值给数组。在 C
语言中,数组名是常量,不能作为左值。
C. char s[10]; *s="right!";
-
这也是错误的。*s
是 s
数组的第一个元素(一个字符),不能将整个字符串字面量赋值给单个字符。
D. char *p="right!";
- 这是正确的。这里 p
被定义为指向字符的指针,并且直接初始化为指向字符串字面量 "right!"。在 C
语言中,字符串字面量存储在静态内存区,p
会指向这个位置。
因此,正确的答案是 D:char *p="right!";
。
1-5
若有定义int a[2][3]
;则对a
数组的第i
行第j
列元素值的正确引用是(
)。
A.*(*(a+i)+j)
B.(a+i)[j]
C.*(a+i+j)
D.*(a+i)+j
GPT
在 C 语言中,对于一个二维数组的元素引用,如果数组定义为
int a[2][3];
,则对数组的第 i
行第
j
列元素的正确引用方式可以通过理解数组的内存布局来得到。对于这个定义,a
是一个有 2 行 3 列的二维数组。
选项分析:
A. *(*(a+i)+j)
- 这是正确的。在这里,a+i
首先定位到第 i
行,然后 *(a+i)
得到该行的首地址,最后通过 +j
定位到第 j
列,并通过外部的 *
获取该位置的值。
B. (a+i)[j]
- 这种写法不正确。在这里,a+i
定位到第 i
行,但 (a+i)[j]
试图在行指针上直接应用下标,这不会得到期望的元素。
C. *(a+i+j)
- 这是错误的。这样会将 a
当作一个线性数组来处理,而不是一个二维数组。这会导致错误的内存访问。
D. *(a+i)+j
- 这也是错误的。*(a+i)
得到的是第 i
行的首地址,但 +j
仅仅是在这个地址上加了 j
,而不是访问第 j
列的元素。
因此,正确答案是 A:*(*(a+i)+j)
。
1-6
若有定义char *cc[2]={"1234","5678"}
;以下叙述中正确的是(
)。
A.cc
数组的两个元素中各自存放了字符串"1234"
和"5678"
的首地址
B.cc
数组的两个元素分别存放的是含有4个字符的一维字符数组的首地址
C.cc
是指针变量,它指向含有两个数组元素的一维字符数组
D.cc
数组元素的值分别是"1234"
和"5678"
GPT
在 C 语言中,char *cc[2]={"1234","5678"};
的定义创建了一个指针数组。我们逐个分析给出的选项:
A. cc数组的两个元素中各自存放了字符串"1234"和"5678"的首地址 -
这个描述是正确的。cc
是一个指针数组,其元素是字符指针。在这个声明中,cc[0]
指向字符串 "1234" 的首地址,而 cc[1]
指向字符串 "5678"
的首地址。
B. cc数组的两个元素分别存放的是含有4个字符的一维字符数组的首地址 -
这个描述基本正确,但有一点误导。字符串 "1234" 和 "5678"
实际上是含有5个字符的数组(包括结尾的空字符 '\0')。所以,虽然
cc[0]
和 cc[1]
确实指向一维字符数组的首地址,但这些数组包含的字符数是 5,而不是 4。
C. cc是指针变量,它指向含有两个数组元素的一维字符数组 -
这个描述不正确。cc
不是一个单独的指针变量,而是一个指针数组。每个元素指向一个字符串,而不是
cc
指向一个包含两个元素的数组。
D. cc数组元素的值分别是"1234"和"5678" -
这个描述不准确。cc
数组的元素是指针,它们存储的是字符串的地址,而不是字符串本身。
综上所述,正确答案是 A:cc数组的两个元素中各自存放了字符串"1234"和"5678"的首地址。
1-7
以下哪个选项中的p是指针:
A.int* *p();
B.int *p();
C.int (*p)[5];
D.int *p[6];
GPT
让我们逐一分析每个选项,以确定哪些选项中的 p
是指针:
A. int* *p();
- 这声明了一个函数
p
,该函数返回一个指向指针的指针(指针的指针)。因此,这里的
p
是一个函数,而不是指针。
B. int *p();
- 这同样声明了一个函数
p
,该函数返回一个指向 int
的指针。与选项 A
一样,这里的 p
是一个函数名称,而不是指针。
C. int (*p)[5];
- 这声明了一个指针
p
,它指向一个有 5
个整数的数组。在这个声明中,p
是一个指针。
D. int *p[6];
- 这声明了一个数组
p
,该数组由 6 个指向 int
的指针组成。因此,p
在这里是一个数组,而不是单个指针。
根据以上分析,唯一的选项,其中 p
是指针,是
C:int (*p)[5];
。
1-8
若有函数max(a,b),并且已使函数指针变量p指向函数max,当调用函数时,正确的调用方法是
A.(*p)max(a+b);
B.*pmax(a,b);
C.(*p)(a,b);
D.*p(a,b);
GPT
在 C 语言中,当你有一个指向函数的指针变量
p
,并且想通过这个指针调用函数,正确的语法是使用
(*p)(arg1, arg2, ...)
, 其中 arg1
,
arg2
, ...
是传递给函数的参数。基于这个规则,我们来分析给出的选项:
A. (*p)max(a+b);
-
这个调用不正确。首先,max(a+b)
是错误的参数传递方式,因为它看起来像是在传递一个单一的参数(a+b
的结果)。此外,语法 (*p)max
也不正确,因为它没有正确地使用括号调用通过指针 p
指向的函数。
B. *pmax(a,b);
-
这个调用也不正确。这里没有正确地使用括号来调用函数指针。*pmax
会被解释为尝试解引用 pmax
,而不是 p
。
C. (*p)(a,b);
- 这是正确的调用方法。使用
(*p)
来正确地解引用函数指针,并使用 (a,b)
传递参数给 max
函数。
D. *p(a,b);
-
这个调用方法不正确。虽然它看起来像是在尝试通过指针调用函数,但它没有正确地使用
(*p)
来解引用函数指针。
因此,正确答案是 C:(*p)(a,b);
。
1-9
以下程序段运行后x的值为( )。
A.2
B.4
C.6
D.8
1-10
对于以下程序,能够正确表示二维数组 t 的元素地址的表达式是( )。
A.*pt[0]
B.*(pt+1)
C.&pt[2]
D.&t[3][2]
GPT
在 C 语言中,理解数组和指针的地址是非常重要的。首先,让我们理解程序中的每个部分是如何工作的:
t
是一个 3x2 的二维整数数组。pt
是一个指针数组,每个元素都是指向int
的指针。在循环中,pt[k]
被设置为指向t
的第k
行。
现在,让我们分析给定的选项:
A. *pt[0]
- 这是 pt
数组的第一个元素(即
pt[0]
)的解引用。由于
pt[0] = t[0]
,*pt[0]
实际上是
t[0][0]
的值,而不是地址。
B. *(pt+1)
- 这是指针 pt
加 1
后的解引用。由于 pt+1
是 pt
数组的第二个元素的地址,*(pt+1)
等价于
pt[1]
,即 t[1]
的地址,也就是
t[1][0]
的地址。
C. &pt[2]
- 这是 pt
数组中第三个元素的地址。由于
pt[2] = t[2]
,&pt[2]
是指向
t[2]
(即 t[2][0]
的地址)的指针的地址,而不是
t[2][0]
的直接地址。
D. &t[3][2]
- 这实际上是指向 t
数组之外的地址,因为 t
的大小只是 3x2,所以
t[3][2]
超出了数组的界限。
根据这些分析,正确表示二维数组 t
的某个元素地址的表达式是 B:*(pt+1)
,它表示
t[1][0]
的地址。
4-1
输入2个字符串,比较它们的大小。要求定义和调用函数cmp(s, t)
,该函数逐个比较字符串s
和t
中的对应字符,直到对应字符不等或比较到串尾。若s
和t
相等则返回0,若不相等则返回不相等字符的差值,即若s
大于t
则返回一个正数,若s
小于t
则返回一个负数。输入输出示例如下:
输入:
输出:
Code
4-2
先消除输入字符串s的前后空格,再判断其是否为“回文”(即字符串正读和倒读都是一样的),若是则输出YES,否则输出NO。
4-3
从键盘输入10个整数,求出其中的最大数。要求用指针变量访问数组的元素。
5-1 调整数组使奇数全部都位于偶数前面其他数字顺序不变
输入一个长度不超过20的数字字符串,调整其顺序使奇数全部都位于偶数前面其他数字顺序不变。
函数接口定义:
在这里描述函数接口。例如:
该函数功能是,将数组s的顺序按题目要求发生改变。
裁判测试程序样例:
在这里给出函数被调用进行测试的例子。例如:
输入样例:
在这里给出一组输入。例如:
输出样例:
在这里给出相应的输出。例如:
Code:
5-2 数组区段的最大最小值
本题要求实现一个函数,找出数组中一部分数据的最大值和最小值。
题目保证没有无效数据。
函数接口定义:
其中 from和to都是用户传入的参数,分别存放数组部分数据的起始地址和结束地址,并且from<=to。
其中max和min为用户传入的地址,分别用于在sublistMaxMin中保存from至to对应区段中数组元素的最大值和最小值的地址。
裁判测试程序样例:
输入样例:
输出样例:
Code:
5-3 字符串反转
字符串反转,如将字符串 "www.runoob.com" 反转为 "moc.boonur.www"。
函数接口定义:
在这里描述函数接口。例如:
在这里解释接口参数。例如:其中 s 是用户传入的参数。
裁判测试程序样例:
在这里给出函数被调用进行测试的例子。例如:
输入样例:
在这里给出一组输入。例如:
输出样例:
在这里给出相应的输出。例如:
Code:
5-4 复制部分字符串
有一个字符串,包含n个字符,写一个函数,将此字符串中从第m个字符开始的全部字符复制成为另外一个字符串。
函数接口定义:
函数接口: 其中 *p1
和*p2
都是用户传入的参数。 m
是复制字符的开始位置。
裁判测试程序样例:
输入样例:
在这里给出一组输入。例如:
输出样例:
在这里给出相应的输出。例如:
Code:
6-1 挑选整数
输入一个字符串,内有数字和非数字字符,例如:a123x67 222y35i088 09x8 c
,请编写程序,将其中连续的数字作为一个整数,依次存放到一维数组a
中。例如前面的字符串,应将123
存放到a[0]
中,67
存放到a[1]
中……,最后输出整数的个数以及各个整数的值。
输入格式:
长度不超过100的一个字符串,其中包含整数字符和非整数字符。
输出格式:
第一行输出整数的个数
第2行输出各个整数的值,以空格间隔,最后一个整数后面没有空格。
输入样例:
输出样例:
Code
6-2 滤字符
以指针的方式,将某个字符串中出现的特定字符删去,然后输出新的字符串。
输入格式:
首先输入一个正整数T,表示测试数据的组数,然后是T组测试数据。 每组测试数据输入一个字符串s和一个非空格字符t。其中s的长度不超过100,且只包含英文字母。
输出格式:
对于每组测试,将删掉t后新得到的字串输出。如果串被删空,则输出NULL。
输入样例:
输出样例:
Code
6-3 放置最值元素
要求将一个n×n矩阵中的最大元素放在中心,4个角分别放4个最小的元素(按从左到右、从上到下的顺序依次从小到大存放)。若有多个同一类元素,则优先选择行号小的,若行号相同则优先选择列号小的。注意,放置元素时通过交换操作实现,具体参看样例。
输入格式:
测试数据有多组,处理到文件尾。每组测试的第一行输入自然数n(n为奇数且3≤n≤11),第二行开始的n行每行输入n个不超过2位的整数。
输出格式:
对于每组测试,输出将矩阵中的最大元素和4个最小元素放到指定的位置后的矩阵。每行的各个数据之间留一个空格。
输入样例:
输出样例:
Code
6-4 sdut-C语言实验-虎子的难题
稷下英才实验班有个同学叫虎子,有一天虎子刷到了一道编程题:给\(M(M<=100)\)组数据,每组数据有\(N\)个正整数\((N<=100)\),要求把每组的\(N\)个数按升序排成一行。虎子觉得应该用指针和函数实现比较高效,但总是调试不出来,你能帮帮他吗?
输入格式:
输入包括\(M+1\)行,第一行是两个正整数\(M、N\);\(M\)表示总共多少组数据,下面\(M\)行每行包含\(N\)个正整数。(输入数据之间会用空格隔开)
输出格式:
输出包括\(M\)行,每行分别对应输入中\(M\)组数据的升序序列,数与数之间用一个空格隔开。
输入样例:
输出样例:
在这里给出相应的输出。例如: