今天在写插入排序实现代码的时候,发现了自己的知识漏洞
发现
测试用的代码
int main(void) {
int arr[10] = { 9,2,8,1,7,3,6,4,6,0 };
for (int i = 0; i < 10; i++) {
printf("%d ", arr[i]);
}
StraightInsertion_Sort(arr);
printf("排序后\n");
for (int i = 0; i < 10; i++) {
printf("%d ", arr[i]);
}
}
插入排序函数实现代码
void StraightInsertion_Sort(int*arr) {
int len = strlen(arr);
int i,j,temp;
for (i = 1; i < len; i++) {//第一个元素时为有序,直接从数组下标为1的第二个元素开始去遍历数组
temp = arr[i];//1.先保存此时遍历到的元素
//2.用此元素与前面的有序列比较以插入正确的位置
for (j = i-1 ;j>=0&&arr[j]>temp;j--) {//j直接索引到前面有序序列的最后一个元素,往前寻找合适位置
arr[j + 1] = arr[j]; //将前面元素大于temp的往后移
}
arr[j+1] = temp; //当此时j指向的元素小于或等于temp时,跳出内层循环,arr[j+1]的就是temp的归途了
}
}
我直接在这个函数里头计算arr的长度
而我调试这个函数发现我的函数并没有实现相应的功能,在我调试的过程中,发现每次函数内len都等于1
探索
然后我开始去找到别人的代码
void InsertionSort(int* arr,int arrSize){
int i,j,temp;
for(i=1;i<arrSize;i++){
temp=arr[i];
for(j=i-1;j>=0&&arr[j]>temp;j--){
arr[j+1]=arr[j];
}
arr[j+1]=temp;
}
}
发现别人函数是直接接受所传过来的数组大小而不是在函数内部单独计算
解决
然后我开始意识到这个问题
函数调用过程中要将数组大小也传过去,不能另一个函数里头单独计算
然后我去问通义千问想跟深入理解一下这个问题
然后学习到下面这些:
在C语言中,当你将数组作为参数传递给函数时,数组并非以其原始形式(即包含元素数量的信息)传递。实际上,数组会退化为一个指向其首元素的指针。这意味着在函数内部,你接收到的不再是一个包含长度信息的数组,而只是一个指针,失去了数组的实际大小信息。
这是因为C语言中的数组参数传递遵循以下规则:
数组退化为指针:当数组被用作函数参数时,它会被自动转换为指向其首个元素的指针。这表示传递给函数的不是整个数组结构,而是数组第一个元素的地址。
失去长度信息:由于数组转换成了指针,编译器在函数内部无法直接获取到数组的长度信息。sizeof运算符在函数内部应用于这个指针时,只会返回指针本身的大小,而不是原来数组的大小。
因此,如果需要在函数中计算数组长度,你需要采取以下几种方式之一:
传递数组长度作为额外参数:最直接的方法是在调用函数时,除了数组指针外,还传递一个表示数组长度的整数值。
使用终止符:对于字符数组(字符串),可以利用空字符\0作为终止符,使用strlen函数计算长度,但这不适用于非字符串的整型或其他类型数组。
使用宏或封装结构:可以在定义数组时使用宏定义或者创建一个包含数组和其长度的结构体,从而间接传递数组长度信息。
总之,直接在函数内部计算传递过来的数组长度通常是不可行的,除非采用额外的机制来传递或推断数组的长度信息。