【C语言实战:实现数组的重复拼接(动态内存+指针参数详解)】
今天在C语言学习中,完成了一个简单却富含知识点的实战案例——将一个数组重复拼接成原长度2倍的新数组。看似简单的功能,却串联了动态内存分配、指针参数传递、数组长度计算等核心知识点,特此记录分享。
一、需求与核心思路
功能需求
输入一个整型数组,输出一个新数组,新数组是原数组的连续重复(例如输入 {1,2,3} ,输出 {1,2,3,1,2,3} )。
核心思路
1. 计算原数组长度,确定新数组长度为原长度的2倍;
2. 动态分配新数组所需内存(避免静态数组长度固定的局限);
3. 通过循环将原数组元素分两次存入新数组;
4. 利用指针参数返回新数组长度,最终返回新数组指针。
二、完整代码实现

代码实现:
#include <stdio.h>
#include <stdlib.h> // malloc函数所需头文件
// 函数功能:生成原数组重复两次的新数组
// nums:原数组指针(数组名本质是首元素地址)
// numsSize:原数组长度
// returnSize:输出参数,用于返回新数组长度
int* get(int* nums, int numsSize, int* returnSize)
{
// 动态分配新数组内存:原长度×2 × 单个int字节数
int* ans = (int*)malloc(numsSize * 2 * sizeof(int));
// 循环填充新数组:前半部分存原数组,后半部分重复存原数组
for (int i = 0; i < numsSize; i++)
{
ans[i] = nums[i]; // 新数组前半段
ans[i + numsSize] = nums[i]; // 新数组后半段(偏移原长度)
}
*returnSize = numsSize * 2; // 通过指针修改外部变量,返回新数组长度
return ans; // 返回动态分配数组的指针
}
int main()
{
int nums[] = {1,2,3}; // 原数组
// 计算原数组长度:数组总字节数 ÷ 单个元素字节数
int numsSize = sizeof(nums) / sizeof(nums[0]);
int returnSize = 0; // 用于接收新数组长度
// 调用函数,传入原数组、原长度、返回长度的地址
int *gtr = get(nums, numsSize, &returnSize);
// 遍历输出新数组
printf("拼接后的数组:");
for (int i = 0; i < returnSize; i++)
{
printf("%d ", *(gtr + i)); // 指针偏移访问数组元素(等价于gtr[i])
}
// 注意:动态分配的内存需手动释放,避免内存泄漏
free(gtr);
gtr = NULL; // 避免野指针
return 0;
}
输出结果:

三、关键知识点拆解
1. 数组长度计算: sizeof(nums) / sizeof(nums[0])
C语言中数组名作为参数传递时会退化为指针,无法在函数内部通过 sizeof 获取真实长度,因此必须在主函数中计算后传入。核心逻辑是:数组总字节数除以单个元素字节数,无论数组类型如何都适用,是通用的数组长度计算方法。
2. 动态内存分配: malloc 的核心用法
- 函数原型: void* malloc(size_t size) ,需包含 <stdlib.h> 头文件;
- 作用:在堆区申请连续内存,大小由参数指定(单位:字节),返回通用指针 void* ,需强制转换为目标类型(如 int* );
- 本案例中: numsSize * 2 * sizeof(int) 确保申请足够存储2倍原数组的内存,避免内存不足导致越界。
3. 指针参数:通过 int* returnSize 返回结果
C语言函数参数传递是值传递,若需修改外部变量的值,必须传递变量地址(指针)。这里通过 *returnSize = numsSize * 2 ,将新数组长度传递回主函数,完美解决了“函数只能返回一个值”的局限。
4. 内存释放: free 的必要性
动态分配的内存不会随函数结束自动释放,若不调用 free 会导致内存泄漏(堆区内存被占用但无法复用)。释放后将指针置为 NULL ,可避免野指针(指向已释放内存的指针)引发的非法访问。
四、运行结果与注意事项
运行结果
plaintext
拼接后的数组:1 2 3 1 2 3
重要注意事项
1. malloc 申请内存可能失败(返回 NULL ),实际开发中需添加判断:
if (ans == NULL) {
*returnSize = 0;
return NULL;
}
2. 避免野指针:释放内存后必须将指针置为 NULL ,否则指针仍指向原内存地址,后续操作可能破坏系统内存;
3. 数组与指针的关系: *(gtr + i) 等价于 gtr[i] ,前者是指针偏移访问,后者是数组下标访问,本质完全相同。
五、学习总结
这个案例看似简单,却覆盖了C语言的核心难点:动态内存管理、指针参数传递、数组与指针的关系。通过实战发现,很多知识点单独学习时容易理解,但结合起来运用才是真正的掌握。尤其是 malloc 与 free 的配对使用、指针参数的传递逻辑,都是实际开发中高频用到的技能,需要反复练习巩固。
后续可以尝试扩展功能:比如将数组重复N次(由参数指定)、支持不同类型数组(如 float 、 char ),进一步深化对动态内存和指针的理解~
