通过使用&;将数组重新分配给其中一个元素来减少数组;c中的运算符
我为二进制搜索编写了一个简单的递归函数,它包含三个参数:整数数组、数组长度和要查找的值。其思想是,在每次递归调用时,它要么将长度减半,并将数组[0]保持在适当的位置,要么将起始索引移到中间(在我的示例中,从底部算起的第三行)。直到找到值或长度为0为止 然后我看到了这个讨论: 这里说数组名是常量,不能在C中重新赋值。所以我的问题是为什么这段代码有效通过使用&;将数组重新分配给其中一个元素来减少数组;c中的运算符,c,arrays,pointers,C,Arrays,Pointers,我为二进制搜索编写了一个简单的递归函数,它包含三个参数:整数数组、数组长度和要查找的值。其思想是,在每次递归调用时,它要么将长度减半,并将数组[0]保持在适当的位置,要么将起始索引移到中间(在我的示例中,从底部算起的第三行)。直到找到值或长度为0为止 然后我看到了这个讨论: 这里说数组名是常量,不能在C中重新赋值。所以我的问题是为什么这段代码有效 int rsearch( int needle, int haystack[], int size ) { if (size == 0) {
int rsearch( int needle, int haystack[], int size ) {
if (size == 0) {
printf("%i not found\n", needle);
return 0;
}
int mid = size / 2;
if (haystack[mid] == needle) {
printf( "found %i in the array\n", needle );
return 1;
} else if (haystack[mid] > needle) {
return rsearch( needle, haystack, size / 2 );
} else {
haystack = &haystack[mid + 1];
return rsearch( needle, haystack, (size - 1) / 2 );
}
我只是在学习,我对指针的知识非常有限。这里没有实际应用。只是好奇
附言。
另一个问题是,当分配给原始数组的内存以这种方式减少时,会发生什么情况?它是再次可用还是内存泄漏?作为函数参数,如下所示:
int haystack[]
相当于:
int *haystack
这主要是因为数组在传递给函数时衰减为指向第一个元素的指针
因此,您拥有的不是数组,而是指针。与数组不同,指针是一个可修改的左值,因此允许将其赋值。数组用作函数参数时,实际上是指向数组的指针,而不是数组作为值。因此,以下函数签名是等效的:
无效测试(int-xptr[10])
,无效测试(int-xptr[])
,以及无效测试(int*xptr)
但是,在定义数组时,只能初始化它的值,但以后不能指定任何其他值
当你把一个数组传递给一个函数时,比如说,int x[10]
,只需使用x
作为参数,就像在test(x)
中一样,然后数组x
自动衰减为指向x
的第一个元素的指针
请参见以下显示差异的代码:
#include <stdio.h>
void test(int xptr[10]) {
printf("value of xptr[0]: %d\n", xptr[0]); // -> 0
xptr = &xptr[2]; // OK; xptr will point to element 2
printf("value of xptr[0]: %d\n", xptr[0]); // -> 2
}
int main(){
int x[10] = { 0,1,2,3,4,5,6,7,8,9 };
// x = &x[2]; // Error: Array type 'int [10]' is not assignable
// but:
test(x); // OK; and is eqivalent to...
test (&x[0]); // OK;
return 0;
}
#包括
无效测试(int xptr[10]){
printf(“xptr[0]的值:%d\n”,xptr[0]);//->0
xptr=&xptr[2];//确定;xptr将指向元素2
printf(“xptr[0]的值:%d\n”,xptr[0]);//->2
}
int main(){
int x[10]={0,1,2,3,4,5,6,7,8,9};
//x=&x[2];//错误:数组类型“int[10]”不可赋值
//但是:
测试(x);//好;与…相等。。。
测试(&x[0]);//确定;
返回0;
}
根据C标准(6.7.6.3功能声明器(包括原型))
7应调整“类型数组”的参数声明
到“类型的限定指针”
和(6.3.2.1左值、数组和函数指示符)
3除非它是sizeof运算符或一元数的操作数&
运算符,或是用于初始化数组的字符串文字
类型为“”的数组“”的表达式转换为
类型为“指向类型的指针”且指向初始值的表达式
数组对象的元素,并且不是左值。如果数组对象
已注册存储类,行为未定义
因此在这个函数声明中
int rsearch( int needle, int haystack[], int size );
参数int haystack[]
调整为int*haystack
。所以这些函数声明
int rsearch( int needle, int haystack[100], int size );
int rsearch( int needle, int haystack[10], int size );
int rsearch( int needle, int haystack[], int size );
int rsearch( int needle, int *haystack, int size );
声明同一个函数。您可以在程序中包含所有这些声明,因为函数声明可能会出现多次。但是,该函数只能定义一次(如果它不是内联函数)
因此,作为参数传递给函数的数组被隐式转换为指向其第一个元素的指针
考虑到最好像这样声明函数
int rsearch( int needle, const int *haystack, int size );
^^^^^
在这种情况下,该函数也可以用于常量数组
这里说数组名是常量,不能为空
重新分配给C
可以正确地说,数组不是可修改的左值
来自C标准(6.5.16赋值运算符)
2赋值运算符的左侧应为可修改的左值
操作数
和(6.3.2.1左值、数组和函数指示符)
当数组被传递给函数时,它将退化为指针,就函数而言不再是数组。这是微妙的,你可能需要进一步阅读来理解这一点。函数参数也是通过C中的值传递的。因此,函数中的haystack只是指向原始数组开头的指针,而不是数组“name”本身。@kaylum非常感谢。我想我明白了。谢谢。这是非常详尽的。