仅用指针实现数组并集时复制元素出现随机数问题求助
嘿,我看到你在完成教授要求的纯指针数组任务时遇到了麻烦——把第一个数组元素复制到并集数组时得到了随机数。这在纯指针操作里是很常见的问题,基本都是指针移动逻辑或者边界控制出了岔子。我来帮你捋清楚问题根源,再给你完整的实现方案。
先搞清楚核心要求
教授要求全程只用指针,禁止用下标,而且两个输入数组本身都没有重复元素,你提到要“找出共同元素”(也就是交集),但函数名叫get_union,可能是想说并集?我两种情况都给你写出来,你按需选用就行。
复制数组出现随机数的常见原因
- 你可能没正确控制指针的终止条件,导致指针越界访问了未初始化的内存区域
- 或者没有正确初始化结果数组的指针位置,写入到了数组之外的地方
- 也有可能是没记录结果数组的当前长度,后续读取时越界拿到了随机值
纯指针操作的核心要点
所有数组遍历、元素访问都要靠指针自增(++ptr)来移动,绝对不能用arr[i]这种下标形式:
- 遍历数组时,用
数组起始指针 + 数组大小得到数组末尾的下一个位置,作为循环终止条件(比如short *end = set1 + size1;,循环条件就是set1 < end) - 访问元素用
*ptr,写入元素也是*res_ptr = *set1这种形式 - 一定要用一个指针跟踪结果数组的当前写入位置,每写入一个元素就把这个指针自增
完整实现代码
先写交集(找出两个数组的共同元素)
#include <stdio.h> // 纯指针实现:检查目标元素是否在数组中,存在返回1,否则0 int is_exist(short *arr, short size, short target) { short *arr_end = arr + size; while (arr < arr_end) { if (*arr == target) { return 1; } arr++; // 指针移动到下一个元素 } return 0; } // 求交集的函数,最后一个参数用来返回结果数组的实际长度 void get_intersection(short *set1, short size1, short *set2, short size2, short *result_arr, short *result_size) { *result_size = 0; // 初始化结果长度为0 short *res_ptr = result_arr; // 指向结果数组的当前写入位置 short *set1_end = set1 + size1; // 遍历第一个数组的所有元素 while (set1 < set1_end) { // 如果当前元素在第二个数组中存在,就写入结果数组 if (is_exist(set2, size2, *set1)) { *res_ptr = *set1; res_ptr++; (*result_size)++; } set1++; } } // 纯指针实现:打印数组 void print_array(short *arr, short size) { short *arr_end = arr + size; printf("["); while (arr < arr_end) { printf("%hd", *arr); if (arr != arr_end - 1) { printf(", "); } arr++; } printf("]\n"); } int main() { short size1, size2; // 输入第一个数组 printf("请输入第一个数组的大小:"); scanf("%hd", &size1); short set1[size1]; printf("请输入第一个数组的元素:"); short *ptr1 = set1; short *end1 = set1 + size1; while (ptr1 < end1) { scanf("%hd", ptr1); ptr1++; } // 输入第二个数组 printf("请输入第二个数组的大小:"); scanf("%hd", &size2); short set2[size2]; printf("请输入第二个数组的元素:"); short *ptr2 = set2; short *end2 = set2 + size2; while (ptr2 < end2) { scanf("%hd", ptr2); ptr2++; } // 结果数组最大长度是两个数组中较小的那个 short result_arr[size1 < size2 ? size1 : size2]; short result_size; // 调用交集函数 get_intersection(set1, size1, set2, size2, result_arr, &result_size); // 输出结果 printf("两个数组的交集为:"); print_array(result_arr, result_size); return 0; }
如果是并集(合并两个数组并去重)
只需要把get_intersection换成下面这个get_union就行,其他代码不变:
// 纯指针实现:求两个数组的并集(合并去重) void get_union(short *set1, short size1, short *set2, short size2, short *result_arr, short *result_size) { *result_size = 0; short *res_ptr = result_arr; short *set1_end = set1 + size1; short *set2_end = set2 + size2; // 先把第一个数组的所有元素写入结果数组 while (set1 < set1_end) { *res_ptr = *set1; res_ptr++; (*result_size)++; set1++; } // 遍历第二个数组,只写入不在结果数组中的元素 while (set2 < set2_end) { if (!is_exist(result_arr, *result_size, *set2)) { *res_ptr = *set2; res_ptr++; (*result_size)++; } set2++; } }
为什么你之前会得到随机数?
大概率是这些问题:
- 你没有用
set1 + size1作为遍历的终止条件,而是用了固定的循环次数,导致指针越界 - 没有初始化
res_ptr指向结果数组的起始位置,或者写入后没有移动这个指针,后续覆盖了错误的位置 - 没有正确记录结果数组的长度,读取时访问了未写入的内存区域,拿到了随机值
内容的提问来源于stack exchange,提问作者user9154422
相关产品推荐
相关产品推荐

