英文:
Why is the C binary search implementation passing an address instead of an array?
问题
我有这个'C'二分搜索程序:
#include <stdio.h>
typedef int element_t;
int less(a, b) {
if (a < b)
return 1;
return 0;
}
element_t *binary_search(element_t x, element_t *a, int n) {
if (n > 0) {
int mid = n / 2;
if (less(a[mid], x))
return binary_search(x, a+mid+1, n-mid-1);
if (less(x, a[mid]))
return binary_search(x, a, mid);
return a+mid;
}
return NULL;
}
int main(){
int a[5] = {1,2,3,4,5};
printf("%d %d", &a[2], binary_search(3, a, 5));
return 0;
}
我不理解这部分 a+mid+1
,它应该传递一个数组,但实际上传递的是一个地址,为什么会这样呢?a
数组 +
一个整数是关于地址的操作。
我在线上查阅了一些资料,但我无法理解发生了什么,因为在线上说 a+1
是索引为 1 的值的地址。
英文:
I have this C
binary search program:
#include <stdio.h>
typedef int element_t;
int less(a, b) {
if (a < b)
return 1;
return 0;
}
element_t *binary_search(element_t x, element_t *a , int n) {
if (n > 0) {
int mid = n / 2;
if (less(a[mid], x))
return binary_search(x, a+mid+1 , n-mid-1);
if (less(x, a[mid]))
return binary_search(x, a, mid);
return a+mid;
}
return NULL;
}
int main(){
int a[5] = {1,2,3,4,5};
printf("%d %d", &a[2], binary_search(3, a, 5));
return 0;
}
I don't get this part a+mid+1
, it is supposed to pass an array there, but an address is instead, how is that? and array a
+
an integer is about address.
I read online and I can't see what is going on, because online it says a+1
is the address of value at index 1.
答案1
得分: 2
为了回答你的问题,我们首先需要一些定义。
什么是数组?
数组是相同类型的变量集合,它们在内存中是连续的。
在C中,数组的名称(在本例中为a
)是指向第一个元素位置的指针。
例如,在这段代码中:
#include <stdio.h>
int main(){
int a[4]={0,1,2,3,4};
int *ptr=&a;
int *ptr_a=a;
return 0;
}
这两个指针都指向相同的内存位置。
什么是指针?
指针是一个存储内存位置的变量。指针具有特殊的算术操作,当你将1添加到指针时,你不是(总是)移动到下一个内存位置,而是添加指针类型的“权重”。
例如,如果你有一个char指针,你每次添加1字节,但是对于int指针,每次添加1会添加4字节(在64位系统上)。
指针和数组有什么关系?
由于数组名称在添加值时被转换为指针,你正在移动到下一个元素的内存位置。
使用[i]
运算符等同于*(array+i)
。
你可以(这并不意味着你应该)不加区分地使用数组和指针。
这被称为“数组/指针二元性法则”。
英文:
To answer your question we first need a few definitions.
What is an array?
An array is a collection of variables of the same type which are contiguous to each other.
In C, the name of an array (in this case a
) is a pointer to the memory position where the first element is located.
For example in this code:
#include <stdio.h>
int main(){
int a[4]={0,1,2,3,4};
int *ptr=&a;
int *ptr_a=a;
return 0;
}
Both pointers point to the same memory location
What is a pointer?
A pointer is a variable which stores a memory position. Pointers have special arithmetic, when you add 1 to a pointer you are not (always) moving to the next memory position, you are adding the "weight" of the pointer type.
For example, if you have a char pointer you add by 1 byte at a time, but with int pointer you add 4 bytes(on 64-bit systems) each time you add 1.
What happens with pointers and arrays?
Since the array name is converted to a pointer when you add a value to it, you are moving to the memory position your next element is located.
And using the [i]
operator is equivalent to *(array+i)
You can(this doesn't mean you should) use arrays and pointers indistinctively.
This is called "The Array/Pointer Duality Law"
答案2
得分: 2
除非它是sizeof
、_Alignof
或一元&
操作符的操作数,或者是用于声明中初始化字符数组的字符串字面值,类型为“N个元素的T
数组”的表达式将被转换为类型为“指向T
的指针”的表达式,并且表达式的值将是数组的第一个元素的地址。
当您调用一个带有数组参数的函数时,比如
int arr[10];
...
foo( arr );
编译器会将表达式 arr
替换为类似于
foo( &arr[0] );
函数接收到的是一个指针,而不是一个数组。
binary_search
函数中的 a
参数是一个指针,而不是一个数组,因此您可以对它进行指针算术运算。
在函数参数列表中,任何声明为 T a[N]
或 T a[]
的参数都会被“调整”为 T *a
;这三种方式都声明了 a
为指针。
这种行为有其原因。数组下标操作 a[i]
被定义为 *(a + i)
- 给定某个起始地址 a
,偏移 i
个元素并解引用结果。
然而,数组对象不存储地址;当您声明一个数组如下所示
int a[10];
在内存中所得到的是
+---+
a: | | a[0]
+---+
| | a[1]
+---+
...
+---+
| | a[9]
+---+
因此,这就是转换规则。不幸的是,这意味着在大多数情况下,数组都会失去它们的“数组性”。
英文:
Unless it is the operand of the sizeof
, _Alignof
, or unary &
operators, or is a string literal used to initialize a character array in a declaration, an expression of type "N-element array of T
" will be converted, or "decay", to an expression of type "pointer to T
" and the value of the expression will be the address of the first element of the array.
When you call a function with an array argument, such as
int arr[10];
...
foo( arr );
the compiler replaces the expression arr
with something like
foo( &arr[0] );
and what the function receives is a pointer, not an array.
The a
parameter in the binary_search
function is a pointer, not an array, so you can do pointer arithmetic on it.
In a function parameter list any parameters declared as T a[N]
or T a[]
are "adjusted" to T *a
; all three declare a
as a pointer.
There is a reason for this behavior. The array subscript operation a[i]
is defined as *(a + i)
- given some starting address a
, offset i
elements and dereference the result.
However, array objects do not store an address; when you declare an array as
int a[10];
what you get in memory is
+---+
a: | | a[0]
+---+
| | a[1]
+---+
...
+---+
| | a[9]
+---+
Hence the conversion rule. Unfortunately, this means arrays lose their "array-ness" in most circumstances.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论