内容正文:
考试系统的优化(3.指针数组、函数指针、动态内存与项目实施)
一、单项选择题
1、以下定义中,属于指向返回值为整型、且有两个整型参数的函数指针的是( )
A. int *p(int,int);
B. int (*p)(int,int);
C. int p(int,int);
D. int (*p)[int,int];
【答案】B
【解析】函数指针的定义需用括号将*p绑定,int (*p)(int,int)表示p是指针,指向返回值为int、参数为两个int的函数;选项 A 是返回指针值的函数;选项 C 是普通函数;选项 D 语法错误。
2、关于返回指针值的函数,以下描述正确的是( )
A. 函数返回值是一个具体的数据值
B. 函数定义格式为 (*函数名)(参数列表);
C. 返回的指针不能指向局部变量
D. 调用该函数时需要用普通变量接收返回值
【答案】C
【解析】返回指针的函数返回的是内存地址,选项 A 错误;选项 B 是定义格式,但核心注意点是不能返回局部变量的指针(局部变量函数结束后释放内存),否则会导致野指针;选项 D 需要用同类型指针变量接收返回值。
3、以下关于指针数组的描述,正确的是( )
A. 指针数组是指向数组的指针
B. char *name[5];表示定义了 5 个字符型指针变量
C. 指针数组的元素只能指向整型数据
D. 指针数组的元素不能指向字符串
【答案】B
【解析】指针数组是元素为指针的数组,char *name[5]中name是数组,包含 5 个char*类型的指针元素;选项 A 是数组指针的定义;选项 C、D 错误,指针数组元素可以指向任意同类型数据,常用于指向字符串以节省内存。
4、main 函数的参数int argc, char *argv[]中,argc的含义是( )
A. 命令行参数的个数
B. 第一个命令行参数的地址
C. 程序的绝对路径
D. 命令行参数的总长度
【答案】A
【解析】argc是argument count的缩写,表示命令行参数的总个数(包括程序本身的路径);argv是指针数组,存储每个命令行参数的地址。
5、动态内存分配函数malloc的返回值类型是( )
A. int*
B. char*
C. void*
D. double*
【答案】C
【解析】malloc函数返回void*类型指针,表示未确定指向的类型,使用时需要通过强制类型转换转为指定类型的指针,如(int*)malloc(10*sizeof(int))。
6、使用函数指针作为函数参数的核心优势是( )
A. 可以减少代码量
B. 实现统一调用接口,灵活切换不同功能函数
C. 提高函数的执行效率
D. 避免函数重名
【答案】B
【解析】函数指针作为参数时,被调函数可以通过指针调用不同的目标函数,无需修改被调函数代码,只需传入不同函数的地址,增强了程序的灵活性和扩展性。
7、以下关于指向指针的指针(二级指针)的定义,正确的是( )
A. int **p;
B. int *p[];
C. int (*p)[];
D. int *p;
【答案】A
【解析】int **p表示p是一个指针,指向int*类型的指针(即二级指针);选项 B 是指针数组;选项 C 是数组指针;选项 D 是普通一级指针。
8、动态分配的内存使用完毕后,必须调用的函数是( )
A. malloc
B. calloc
C. free
D. realloc
【答案】C
【解析】动态分配的内存位于堆区,系统不会自动释放,必须调用free函数手动释放,否则会造成内存泄漏;选项 A、B 是分配内存的函数,选项 D 是重新分配内存的函数。
9、用指针实现字符串复制str_copy函数,以下核心逻辑正确的是( )
A. while (*from != '\0') { *to = *from; from++; } *to = '\0';
B. while(*from != '\0') { to = from; from++; to++; }
C. while(*from != '\0') { *to++ = *from++; } *to = '\0';
D. while(*from != '\0') { *to = *from++; } *to = '\0';
【答案】C
【解析】选项 C 将赋值和指针自增合并,逻辑简洁,最后添加结束符'\0'保证目标字符串合法;选项A仅递增 from 指针,to 指针位置不变,字符重复覆盖同一位置,不能正确复制字符串,错误。;选项 B 是指针地址赋值,不是字符赋值;选项 D 只移动from指针,to指针未移动,会覆盖同一位置的字符。
10、以下操作中,对函数指针无意义的是( )
A. 赋值为同类型函数的地址
B. 用指针调用指向的函数
C. 对指针进行自增操作(p++)
D. 作为函数参数传递
【答案】C
【解析】函数指针存储的是函数的入口地址,自增操作无法指向合法的函数地址,因此无意义;其他操作均是函数指针的合法用法。
二、判断题
1、函数指针可以指向任意类型的函数,无需匹配返回值和参数类型。( )
【答案】×
【解析】函数指针只能指向与其定义时指定的返回值类型、参数个数和类型完全匹配的函数,否则会导致编译错误或运行异常。
2、返回指针值的函数可以返回局部变量的指针,因为局部变量的值会保留。( )
【答案】×
【解析】局部变量存储在栈区,函数执行结束后会被释放,返回其指针会导致野指针,访问该指针指向的内存会引发不可预期的错误。
3、指针数组char *name[5]和数组指针char (*name)[5]的含义完全相同。( )
【答案】×
【解析】指针数组是存储指针的数组,数组指针是指向数组的指针,二者类型和用途完全不同:指针数组常用于指向多个字符串,数组指针常用于接收二维数组的地址。
4、main 函数的argv[0]存储的是第一个命令行参数的内容。( )
【答案】×
【解析】argv[0]存储的是程序本身的绝对路径或文件名,argv[1]及以后才是用户输入的命令行参数。
5、使用malloc分配内存时,如果分配失败,会返回NULL指针,因此需要判断分配是否成功。( )
【答案】√
【解析】当系统内存不足时,malloc会返回NULL,如果直接使用该指针会导致程序崩溃,因此必须添加判断逻辑处理分配失败的情况。
3、 填空题
1、定义一个指向返回值为double、参数为(double*, int)的函数指针,格式为____。
【答案】double (*p)(double*, int);
【解析】函数指针定义需用括号将*p绑定,依次指定返回值类型、指针变量名、参数列表。
2、返回指针值的函数定义格式为____,例如返回字符指针的函数可以定义为char *str_chr(char *str, char ch);。
【答案】类型名 *函数名(参数列表);
【解析】返回指针的函数需要在函数名前加*,表示函数返回的是指定类型的指针。
3、指针数组int *p[4]表示定义了一个包含____个元素的数组,每个元素都是指向整型数据的指针。
【答案】4
【解析】[4]指定了数组的长度,数组元素的类型是int*,即整型指针。
4、动态分配内存时,为了适配不同编译器的类型字节数,通常使用____函数计算类型的字节数,例如sizeof(int)。
【答案】sizeof
【解析】sizeof可以获取指定类型或变量在当前编译器下的字节数,保证动态分配的内存大小准确。
四、程序填空题
1、题目描述:以下程序通过函数指针实现对数组的不同操作(求和、求最大值),请补充缺失代码。
#include <stdio.h>
// 定义数组求和函数
double arr_sum(double *arr, int n) {
double sum = 0;
for(int i=0; i<n; i++) {
sum += arr[i];
}
return sum;
}
// 定义数组求最大值函数
double arr_max(double *arr, int n) {
double max = arr[0];
for(int i=1; i<n; i++) {
if(arr[i] > max) {
max = arr[i];
}
}
return max;
}
// 定义通用处理函数,参数包含函数指针
void process(double *arr, int n, __(1) __) {
double result = fun(arr, n); // 调用函数指针指向的函数
printf("结果:%.2lf
", result);
}
int main() {
double nums[] = {1.5, 3.8, 5.6, 7.8, 9.1};
int len = sizeof(nums)/sizeof(nums[0]);
printf("数组求和:");
// 调用process函数,传入求和函数的地址
process(nums, len, __(2)__);
printf("数组求最大值:");
// 调用process函数,传入求最大值函数的地址
process(nums, len, __(3) __);
return 0;
}
【答案】
(1) double (*fun)(double*, int)
(2) arr_sum
(3) arr_max
【解析】
(1) 定义函数指针形参,格式要和 arr_sum、arr_max 函数的返回值、参数类型完全一致,用来接收同类函数的地址。
(2) C 语言中函数名代表函数的入口地址,把 arr_sum 作为实参传给函数指针形参,让 fun 指向数组求和函数,调用时就会执行求和逻辑。
(3) 函数名代表函数的入口地址,将arr_sum和arr_max作为实参传入process,即可让函数指针指向对应的函数,实现统一接口调用不同功能。
原创精品资源学科网独家享有版权,侵权必究!
学科网(北京)股份有限公司
$
考试系统的优化(3.指针数组、函数指针、动态内存与项目实施)
一、单项选择题
1、以下定义中,属于指向返回值为整型、且有两个整型参数的函数指针的是( )
A. int *p(int,int);
B. int (*p)(int,int);
C. int p(int,int);
D. int (*p)[int,int];
2、关于返回指针值的函数,以下描述正确的是( )
A. 函数返回值是一个具体的数据值
B. 函数定义格式为 (*函数名)(参数列表);
C. 返回的指针不能指向局部变量
D. 调用该函数时需要用普通变量接收返回值
3、以下关于指针数组的描述,正确的是( )
A. 指针数组是指向数组的指针
B. char *name[5];表示定义了 5 个字符型指针变量
C. 指针数组的元素只能指向整型数据
D. 指针数组的元素不能指向字符串
4、main 函数的参数int argc, char *argv[]中,argc的含义是( )
A. 命令行参数的个数
B. 第一个命令行参数的地址
C. 程序的绝对路径
D. 命令行参数的总长度
5、动态内存分配函数malloc的返回值类型是( )
A. int*
B. char*
C. void*
D. double*
6、使用函数指针作为函数参数的核心优势是( )
A. 可以减少代码量
B. 实现统一调用接口,灵活切换不同功能函数
C. 提高函数的执行效率
D. 避免函数重名
7、以下关于指向指针的指针(二级指针)的定义,正确的是( )
A. int **p;
B. int *p[];
C. int (*p)[];
D. int *p;
8、动态分配的内存使用完毕后,必须调用的函数是( )
A. malloc
B. calloc
C. free
D. realloc
9、用指针实现字符串复制str_copy函数,以下核心逻辑正确的是( )
A. while (*from != '\0') { *to = *from; from++; } *to = '\0';
B. while(*from != '\0') { to = from; from++; to++; }
C. while(*from != '\0') { *to++ = *from++; } *to = '\0';
D. while(*from != '\0') { *to = *from++; } *to = '\0';
10、以下操作中,对函数指针无意义的是( )
A. 赋值为同类型函数的地址
B. 用指针调用指向的函数
C. 对指针进行自增操作(p++)
D. 作为函数参数传递
二、判断题
1、函数指针可以指向任意类型的函数,无需匹配返回值和参数类型。( )
2、返回指针值的函数可以返回局部变量的指针,因为局部变量的值会保留。( )
3、指针数组char *name[5]和数组指针char (*name)[5]的含义完全相同。( )
4、main 函数的argv[0]存储的是第一个命令行参数的内容。( )
5、使用malloc分配内存时,如果分配失败,会返回NULL指针,因此需要判断分配是否成功。( )
3、 填空题
1、定义一个指向返回值为double、参数为(double*, int)的函数指针,格式为____。
2、返回指针值的函数定义格式为____,例如返回字符指针的函数可以定义为char *str_chr(char *str, char ch);。
3、指针数组int *p[4]表示定义了一个包含____个元素的数组,每个元素都是指向整型数据的指针。
4、动态分配内存时,为了适配不同编译器的类型字节数,通常使用____函数计算类型的字节数,例如sizeof(int)。
四、程序填空题
1、题目描述:以下程序通过函数指针实现对数组的不同操作(求和、求最大值),请补充缺失代码。
#include <stdio.h>
// 定义数组求和函数
double arr_sum(double *arr, int n) {
double sum = 0;
for(int i=0; i<n; i++) {
sum += arr[i];
}
return sum;
}
// 定义数组求最大值函数
double arr_max(double *arr, int n) {
double max = arr[0];
for(int i=1; i<n; i++) {
if(arr[i] > max) {
max = arr[i];
}
}
return max;
}
// 定义通用处理函数,参数包含函数指针
void process(double *arr, int n, __(1) __) {
double result = fun(arr, n); // 调用函数指针指向的函数
printf("结果:%.2lf
", result);
}
int main() {
double nums[] = {1.5, 3.8, 5.6, 7.8, 9.1};
int len = sizeof(nums)/sizeof(nums[0]);
printf("数组求和:");
// 调用process函数,传入求和函数的地址
process(nums, len, __(2)__);
printf("数组求最大值:");
// 调用process函数,传入求最大值函数的地址
process(nums, len, __(3) __);
return 0;
}
原创精品资源学科网独家享有版权,侵权必究!
学科网(北京)股份有限公司
$