你也能够上程序咖 (https://meta.chengxuka.com),关上大学幕题板块,岂但有答案,解说,还能够在线答题。
一、选择题
1. 下列语句定义 px 为指向 int 类型变量的指针,正确的是()。
A. int x, *px=x;
B.int x, *px=&x;
C. int *px=&x, x;
D.int x, px=x;
答:B
解析:先定义变量,再定义指针,定义指针应用 *
。为指针赋值为某个变量的地址时应用 & 符。
2. 以下选项中,对根本类型雷同的指针变量不能进行运算的运算符是()。
A. =
B. ==
C. +
D. –
答:C
解析:
选项 A:“=(赋值)”是对于类型雷同的两个指针变量之间惯例运算。
选项 B:“==(比拟相等)”比拟两个指针变量是否雷同。
选项 C:“+”运算是不能够的,因为指针变量是一种非凡的变量,指针变量的值寄存的是所指向变量的地址,两个地址相加并不能保障后果为一个无效的地址值,因此在 C 语言中指针变量相加是非法的。
选项 D:“-(减法)”运算两个雷同指针变量相减能够取得在之间相隔的同类型元素个数(在某个类型的数组中的利用)。
3. 下列程序的输入后果是()。
void f(int *p)
{*p = 5;}
int main(void)
{
int x = 10, *px = &x;
f(px);
printf("%d#", (*px)++);
printf("%d\n", x);
return 0;
}
A.5#6
B.6#6
C.10#11
D.11#11
答:A
解析:这里考查当是指针作为函数的参数。这里将 px 作为实参,传递给函数的形参 p,就示意 p 也指向变量 x 的地址。在函数中操作指针 p,批改 x 的值为 5。当函数完结后,打印 (*px)++
,就是指针 px 对应的变量 x++,5。而后 x 的值自增 1,为 6。
4. 以下程序的输入后果是()。
void sub(int x, int y, int *z)
{*z = y - x;}
int main(void)
{
int a, b, c;
sub(10, 5, &a);
sub(7, a, &b);
sub(a, b, &c);
printf("%d,%d,%d\n", a, b, c);
return 0;
}
A.5,2, 3
B.5, -2, -7
C.-5,-12, -17
D.-5,-12, – 7
答:D
解析:
自定义函数中次要是批改指针 z 指向的变量的值。
在 main() 中,先定义了 3 个变量 a,b,c。因为没有初始值,那么零碎会主动调配随机值。
而后第一次调用 sub() 函数,形参 x 赋值为 10,y 赋值为 5,*z
赋值为 a 的地址,就示意指针 z 指向变量 a 的地址。函数中通过指针 z 批改变量 a 的值为 y-x,就是 -5。
而后第二次调用 sub() 函数,形参 x 赋值为 7,y 赋值为 a,就是刚刚的 -5,*z
赋值为 b 的地址,就示意指针 z 指向变量 b 的地址。函数中通过指针 z 批改变量 b 的值为 y-x,就是 -5-7=-12。
而后第三次调用 sub() 函数,形参 x 赋值为 a,是 -5,y 赋值为 b,就是刚刚的 -12,*z
赋值为 c 的地址,就示意指针 z 指向变量 c 的地址。函数中通过指针 z 批改变量 c 的值为 y-x,就是 -12-(-5)=-7。
5. 若有以下定义,且 0<=i<10,则对数组元素的谬误援用是()。·
int i,a[]={0,1,2,3,4,5,6,7,8,9},*p=a;
A. *(a+i)
B. a[p-a+i]
C. p+i
D. *(&a[i])
答:C
解析:p 是指针类型,要想操作 p 指向的变量,须要应用 *
6. 下列程序段的输入后果是()。
int a[10]={0,1,2,3,4,5,6,7,8,9},*p=a+3;
printf("%d", *++p);
A.3
B.4
C.a[4] 的地址
D. 非法
答:B
解析:数组 a 的长度为 10,a 指向了数组的基地址,也就是第 1 个元素的地址。指针变量 p,初始值为 a+3,就示意指向了 数组 a 中的第 4 个元素的地址,打印的是 ++p 之后示意指向了第 5 个元素,也就是数值 4。
- 对于上面的程序段,叙述正确的是()。
char s[]="china", *p=s;
A. *p
与 s[0] 相等
B. 数组 s 中的内容和指针变量 p 中的内容相等
C. s 和 p 完全相同
D. 数组 s 的长度和 p 所指向的字符串长度相等
答:A
解析:
选项 B,数组 s 中的内容是字符串,p 中的内容是一个地址
选项 C,从指针角度看,s 是常量指针,而 p 不是
选项 D,s 数组的长度是 p 所指向的字符串长度 +1
8. 上面程序段的运行后果是()。
char s[] = "language", *p = s;
while (*p++ != 'u')
{printf("%c", *p - 'a' + 'A');
}
A. LANGUAGE
B. ANGU
C. LANGU
D. LANG
答:B
解析:p 指向字符串首地址,while 判断 p 指向的字符是否为 ‘u’,如果是 ‘u’ 则循环完结,而后将字符转换为大写字符。这里的一个关键问题是,while 中 p++ != ‘u’,是先判断 p != ‘u’,而后 p++,因而判断字符 !=’u’ 后,p 接着就指向了下一个字符 ‘a’,因而 printf 输入的是 ‘A’,当 p 指向字符 ‘g’ 时,也不等于 ‘u’,而后 p 指向下一个字符 ‘u’,因而会输入 ‘U’。最终输入的字符是 ”ANGU”
二、填空題
1. 输入一维数组最大元素和最小元素的下标。査找一维数组的最大元素和最小元素的下示,分別寄存在函数 main() 的 maxsub 和 minsub 变量中。请填空。
void find(int *, int, int *, int *);
int main(void)
{int maxsub, minsub, a[] = {5, 3, 7, 9, 2, 0, 4, 1, 6, 8};
find(____________);
printf("maxsub=%d, minsub=%d\n", maxsub, minsub);
return 0;
}
void find(int *a, int n, int *maxsub, int *minsub)
{
int i;
*maxsub = *minsub = 0;
for (i = 1; i < n; i++)
{if (a[i] > a[*maxsub])
____________;
if (a[i] < a[*minsub])
____________;
}
}
答:
a, 10, &maxsub, &minsub
*maxsub = i
*minsub = i
解析:
find() 函数是为了找到最大值和最小值的下标。这里须要 4 个参数,第一个参数是数组,第二个参数是数组的长度,第三个是要存储最大值下标 maxsub,第四个要存储最小值下标 minsub。
所以第二个空,当数组中的元素值大于 最大值下标对应的数组元素值 a[i] > a[*maxsub]
,那么将 i 的值赋值给最大下标:*maxsub = i
。
第二个空,当数组中的元素值小于 最小值下标对应的数组元素值 a[i] < a[*minsub]
,那么将 i 的值赋值给最小下标:*minsub = i
。
至于第一个空,就是调用函数。传入对应的实参即可。
2. 数组插值。函数 insert() 的性能是在一维数组 a 中将 x 插入到下标为 i(i>=0)的元素前,如果 i>= 元素个数,则 x 插入到开端,元素个数寄存在指针 n 所指向的变量中,插入后元素个数加 1。请填空。
void insert(int a[], int *n, int x, int i)
{
int j;
if (________)
{for (j = *n - 1; ________; j--)
________ = a[j];
}
else
{i = *n;}
a[i] = ________;
(*n)++;
}
答:
i < *n
j >= i
a[j + 1]
x
解析:
第一空,题目说如果 i>= 元素个数,则 x 插入到开端,所以 if 的条件就是 i < *n
,
第二空,循环将 i 前面的元素向后挪动一位。所以第二空是 j >= i。
第三空,向后挪动一位。就是 a[j + 1] = a[j]
第四空,将 x 存入到 i 的地位上。a[i] = x。
3. 判断回文。先打消输出字符串 s 的前后空格,再判断其是否为“回文”(即字符串正读和倒读都是一样的),若是则输入 Yes,否则输入 No。请填空。
char ch, s[80], *p, *q;
int i, j, n;
gets(s);
p = _________;
while (*p == ' ')
{_________;}
n = strlen(s);
q = _________;
while (*q == ' ')
{q--;}
while (_________ && *p == *q)
{
p++;
_________;
}
if (p < q)
printf("No\n");
else
printf("Yes\n");
答:
s
p++
s + n – 1
p < q
q–
解析:
首先将指针 p 指向字符串 s,第一个 while 循环完结后,指针 p 会指到字符串非空的第一个字符,也就是说这个循环用于革除字符串的后面的空格。第二个 while 循环完结后,会去除字符串尾部的空格,指针 q 指向最初一个非空的字符。最初一个 while 循环,这里操作两个指针,判断它俩指向的字符是否雷同,如果雷同,p 从前向后挪动,q 从后向前挪动,如果最初 p 和 q 能重合,就阐明是回文字符串,否则就不是。
4. 最大字符移位。在字符串 str 中找出最大的字符,将在该字符前的所有字符往后程序挪动一位,再把最大字符放在字符串的第一个地位上。如 ” knowedge” 变成 “wknoledge”。请填空。
char max, str[80], *p = str, *q = str;
gets(p);
max = *(p++);
while (*p != '\0')
{if (max < *p)
{
max = *p;
__________;
}
p++;
}
p = q;
while (__________)
{
__________;
p--;
}
*p = max;
puts(p);
答:
q = p
p != str
*p = *(p - 1)
解析:
第一个空,q 指向以后的最大字符,所以一旦判断 max <*p
,那么就取 p 赋值给 q。始终循环到整个字符串完结,q 就指向了整个字符串中的最大字符。
而后将 p 也设置到 q 指向的地位,而后将 p 后面的字符,每一个都向后挪动一位。直到字符串结尾,所以循环条件就是 p != str。
最初再将 max 的字符,赋值到字符串结尾即可。
5. 字符传送。将字符串 s1 的所有字符传送到字符串 s2 中,要求每传送 3 个字符就再寄存一个星号。如字符串 s1 为 “abedefg”,则字符串 s2 为 "abe*def*g"
。请填空。
char s1[80], s2[80], *p = s1;
int cnt = 0, k = 0;
gets(p);
while (*p != '\0')
{s2[k] = *p;
k++;
p++;
cnt++;
if (_________)
{s2[k] = '*';
_________;
_________;
}
}
s2[k] = '\0';
puts(s2);
答:
cnt == 3
cnt = 0
k++
解析:
每传送 3 个字符,就要放一个星号,所以 cnt 为 3 的时候,搁置星号,而后 cnt 要从新置为 0,k 要持续 ++。
三、程序设计题
题目 1:拆分实数的整数与小数局部:要求自定义一个函数 void splitfloat (float x,int *intpart, float *fracpart)
,其中 x 是被拆分的实数,* intpart
和 * fracpart
别离是将实数 x 拆分进去的整数局部与小数局部。编写主函数,并在其中调用函数 splitfloat()。试编写相应程序。
答案代码:
#include <stdio.h>
void splitfloat(float x, int *intpart, float *fracpart);
int main(void)
{// 习题 (8.3.1)
/*
拆分实数的整数与小数局部:要求自定义一个函数 void splitfloat (float x,int *intpart, float *fracpart),其中 x 是被拆分的实数,* intpart 和 * fracpart 别离是将实数 x 拆分进去的整数局部与小数局部。编写主函数,并在其中调用函数 splitfloat()。*/
float x, fracpart;
int intpart;
printf("input number:");
scanf("%f", &x);
splitfloat(x, &intpart, &fracpart);
printf("intpart=%d\n", intpart);
printf("fracpart=%f\n", fracpart);
return 0;
}
void splitfloat(float x, int *intpart, float *fracpart)
{*intpart = (int)x;
*fracpart = x - *intpart;
}
运行后果:
题目 2:在数组中查找指定元素:输出一个正整数 n(1<n≤10),而后输出 n 个整数存入数组 a 中,再输出一个整数 x,在数组 a 中查找 x,若找到则输入相应的下标,否则显示 Not found。要求定义和调用函 search(int lis[], int n, int x),在数组 list 中查找元素 x,若找到则返回相应下标,否则返回 -1,参数 n 代表数组 list 中元素的数量。试编写相应程序。
答案代码:
#include <stdio.h>
int main(void)
{// 习题 (8.3.2)
/*
在数组中查找指定元素:输出一个正整数 n(1<n≤10),而后输出 n 个整数存入数组 a 中,再输出一个整数 x,在数组 a 中查找 x,若找到则输入相应的下标,否则显示 Not found。要求定义和调用函 search(int lis[], int n, int x),在数组 list 中查找元素 x,若找到则返回相应下标,否则返回 -1,参数 n 代表数组 list 中元素的数量。*/
int i, n, res, x;
int a[10];
int search(int list[], int n, int x);
printf("input n:");
scanf("%d", &n);
printf("input %d number:\n", n);
for (i = 0; i < n; i++)
scanf("%d", &a[i]);
printf("input x:");
scanf("%d", &x);
res = search(a, n, x);
if (res != -1)
printf("index = %d\n", res);
else
printf("Not found\n");
return 0;
}
int search(int list[], int n, int x)
{
int i;
for (i = 0; i < n; i++)
if (list[i] == x)
return i;
return -1;
}
运行后果:
题目 3:循环后移:有 n 个整数,使后面各数程序向后移 m 个地位,移出的数再从结尾移入。编写一个函数实现以上性能,在主函数中输出 n 个整数并输入调整后的 n 个数。试编写相应程序。
答案代码:
#include <stdio.h>
void mov(int *x, int n, int m);
int main(void)
{// 习题 (8.3.3)
/*
循环后移:有 n 个整数,使后面各数程序向后移 m 个地位,移出的数再从结尾移入。编写一个函数实现以上性能,在主函数中输出 n 个整数并输入调整后的 n 个数。*/
int i, m, n;
int a[80];
printf("input n,m:");
scanf("%d%d", &n, &m);
printf("input %d number:\n", n);
for (i = 0; i < n; i++)
scanf("%d", &a[i]);
mov(a, n, m);
printf("After move:");
for (i = 0; i < n; i++)
printf("%d", a[i]);
printf("\n");
return 0;
}
/* 函数 mov(x,m) 实现循环挪动的性能, 函数形参 x 的类型是整型指针, 形参 n 和 m 的类型是 int, 函数的类型是 void。*/
void mov(int *x, int n, int m)
{
int i, j, k;
for (i = 1; i <= m; i++)
{k = x[n - 1];
for (j = n - 1; j > 0; j--)
x[j] = x[j - 1];
x[0] = k;
}
}
运行后果:
题目 4:报数:有 n 集体图成一圈,按程序从 1 到 n 编好号。从第一个人开始报数,报到 m(m<n)的人退出圈子,下集体从 1 开始报数,报到 m 的人退出圈子。如此上来,直到留下最初一个人。输出整数 n 和 m,并按退出程序输入退出圈子的人的编号。试编写相应程序。
答案代码:
#include <stdio.h>
int main(void)
{// 习题 (8.3.4)
/*
报数:有 n 集体图成一圈,按程序从 1 到 n 编好号。从第一个人开始报数,报到 m(m<n)的人退出圈子,下集体从 1 开始报数,报到 m 的人退出圈子。如此上来,直到留下最初一个人。输出整数 n 和 m,并按退出程序输入退出圈子的人的编号。*/
int count, i, m, n, no;
int num[50];
int *p;
printf("input n and m:");
scanf("%d%d", &n, &m);
for (i = 0; i < n; i++)
num[i] = i + 1;
p = num;
count = no = 0;
while (no < n - 1)
{if (*p != 0)
count++;
if (count == m)
{
no++;
printf("No%d: %d\n", no, *p);
*p = 0;
count = 0;
}
p++;
if (p == num + n)
p = num;
}
p = num;
while (*p == 0)
p++;
printf("Last No is: %d\n", *p);
return 0;
}
运行后果:
题目 5:应用函数实现字符串复制:输出一个字符串 t 和一个正整数 m,将字符串 t 中从第 m 个字符开始的全副字符复制到字符串 s 中,再输入字符串 s。要求自定义并调用函数 void strmcpy(char *s,char *t,int m)
。试编写相应程序。
答案代码:
#include <stdio.h>
#include <string.h>
int main(void)
{// 习题 (8.3.5)
/*
应用函数实现字符串复制:输出一个字符串 t 和一个正整数 m,将字符串 t 中从第 m 个字符开始的全副字符复制到字符串 s 中,再输入字符串 s。要求自定义并调用函数 void strmcpy(char *s,char *t,int m)。*/
char s[80], t[80];
int m;
void strmcpy(char *s, char *t, int m);
printf("input string t:\n");
gets(t);
printf("input number m:");
scanf("%d", &m);
getchar();
if (strlen(t) < m)
printf("error input");
else
{strmcpy(s, t, m);
puts(s);
}
return 0;
}
void strmcpy(char *s, char *t, int m)
{
t = t + m - 1;
while (*t != '\0')
{
*s = *t;
s++;
t++;
}
*s = '\0';
}
运行后果:
题目 6:删除字符:输出一个字符串,再输出一个字符 ch,将字符串中所有的 ch 字符删除后输入该字符串。要求定义和调用函数 delchar(s, c),该函数将字符串 s 中呈现的所有 c 字符删除。试编写相应程序。
答案代码:
#include <stdio.h>
#include <string.h>
int main(void)
{// 习题 (8.3.6)
/*
删除字符:输出一个字符串,再输出一个字符 ch,将字符串中所有的 ch 字符删除后输入该字符串。要求定义和调用函数 delchar(s, c),该函数将字符串 s 中呈现的所有 c 字符删除。*/
char c;
char str[80];
void delchar(char *str, char c);
printf("input a string:\n");
gets(str);
printf("input a char:");
scanf("%c", &c);
getchar();
delchar(str, c);
printf("result:");
puts(str);
return 0;
}
void delchar(char *str, char c)
{
int i, j;
i = j = 0;
while (str[i] != '\0')
{if (str[i] != c)
{str[j] = str[i];
j++;
}
i++;
}
str[j] = '\0';
}
运行后果:
题目 7:字符串排序:输出 5 个字符串,按由小到大的程序输入。试编写相应程序。
答案代码:
#include <stdio.h>
#include <string.h>
int main(void)
{// 习题 (8.3.7)
/*
字符串排序:输出 5 个字符串,按由小到大的程序输入。*/
int i, j, index;
char sx[5][80], stemp[80];
printf("input 5 string:\n");
for (i = 0; i < 5; i++)
scanf("%s", sx[i]);
for (i = 1; i < 4; i++)
{
index = i;
for (j = i + 1; j < 5; j++)
if (strcmp(sx[j], sx[index]) < 0)
index = j;
strcpy(stemp, sx[i]);
strcpy(sx[i], sx[index]);
strcpy(sx[index], stemp);
}
printf("after sorted:\n");
for (i = 0; i < 5; i++)
puts(sx[i]);
return 0;
}
运行后果:
题目 8:判断回文:判断输出的一串字符是否为“回文”。所谓“回文”是指顺读和倒读都一样的字符串。如 “XYZYX” 和 “xyzzyx” 都是回文。试编写相应程序。
答案代码:
#include <stdio.h>
int main(void)
{// 习题 (8.3.8)
/*
判断回文:判断输出的一串字符是否为“回文”。所谓“回文”是指顺读和倒读都一样的字符串。如 "XYZYX" 和 "xyzzyx" 都是回文。*/
char s[80];
int mirror(char *p);
printf("input a string:");
gets(s);
if (mirror(s) != 0)
printf("YES\n");
else
printf("NO\n");
return 0;
}
int mirror(char *p)
{
char *q;
q = p;
while (*q != '\0')
q++;
q--;
while (p < q)
{if (*p != *q)
return 0;
p++;
q--;
}
return 1;
}
运行后果:
题目 9:分类统计字符个数:输出一行文字,统计其中的大写字母、小写字母、空格、数字以及其余字符各有多少。试编写相应程序。
答案代码:
#include <stdio.h>
int main(void)
{// 习题 (8.3.9)
/*
分类统计字符个数:输出一行文字,统计其中的大写字母、小写字母、空格、数字以及其余字符各有多少。*/
char s[80];
char *p;
int blank, digit, lower, other, upper;
gets(s);
upper = lower = blank = digit = other = 0;
for (p = s; *p != '\0'; p++)
if (*p >= 'A' && *p <= 'Z')
upper++;
else if (*p >= 'a' && *p <= 'z')
lower++;
else if (*p >= '0' && *p <= '9')
digit++;
else if (*p == ' ')
blank++;
else
other++;
printf("upper: %d lower: %d blank: %d digit: %d other: %d\n", upper, lower, blank, digit, other);
return 0;
}
运行后果:
题目 10:(选做)输入学生问题(动态分配):输出学生人数后输出每个学生的问题,最初输入学生的均匀问题、最高问题和最低问题。要求应用动态内存调配来实现。试编写相应程序。
答案代码:
#include <stdio.h>
#include <stdlib.h>
int main(void)
{// 习题 (8.3.10)
/*(选做)输入学生问题(动态分配):输出学生人数后输出每个学生的问题,最初输入学生的均匀问题、最高问题和最低问题。要求应用动态内存调配来实现。*/
int n, i;
float *p, sum, max, min, avg;
printf("input students' number n: ");
scanf("%d", &n);
/* 为数组 p 动态分配 n 个浮点数 float 类型大小的空间 */
if ((p = (float *)calloc(n, sizeof(float))) == NULL)
{printf("Not able to allocate memory.\n");
exit(1);
}
sum = 0.0;
max = -1; /* 初始化 */
min = 1000;
printf("input %d students' scores: ", n); /* 提醒输出 n 个整数 */
for (i = 0; i < n; i++)
{scanf("%f", p + i);
sum = sum + *(p + i);
if (min > *(p + i))
min = *(p + i);
if (max < *(p + i))
max = *(p + i);
}
avg = sum / n;
printf("The avg is %f, max is %f, min is %f\n", avg, max, min);
free(p); /* 开释动态分配的空间 */
return 0;
}
运行后果: