C 如何在不衰减的情况下将指针传递到数组,并使用';参考';在为野蛮人准备的活动中?
我读过很多关于将数组传递给函数的讨论。它们似乎是为能流利使用C语言的人编写的。我是一个还不能流利使用C语言的野蛮人 从我在其他讨论中所读到的来看,应该可以传递一个数组而不会导致指针衰减。然而,我需要帮助实现这一点。 请给我一个简洁的例子,说明如何将数组作为指针的指针传递,并确定它在传递到的函数中的大小 如果在函数中更改了数组,我希望更改数组的源。我想尽量减少额外的内存分配。 如果可能的话,我想调整函数中数组的大小。 这段代码不需要通过就可以工作C 如何在不衰减的情况下将指针传递到数组,并使用';参考';在为野蛮人准备的活动中?,c,pebble-watch,pebble-sdk,C,Pebble Watch,Pebble Sdk,我读过很多关于将数组传递给函数的讨论。它们似乎是为能流利使用C语言的人编写的。我是一个还不能流利使用C语言的野蛮人 从我在其他讨论中所读到的来看,应该可以传递一个数组而不会导致指针衰减。然而,我需要帮助实现这一点。 请给我一个简洁的例子,说明如何将数组作为指针的指针传递,并确定它在传递到的函数中的大小 如果在函数中更改了数组,我希望更改数组的源。我想尽量减少额外的内存分配。 如果可能的话,我想调整函数中数组的大小。 这段代码不需要通过就可以工作 // this works j = sizeof(
// this works
j = sizeof(hourLongs)/sizeof(hourLongs[0]);
i = 0; while (now > hourLongs[i] && i < j){i++;}
hour = --i;
为sizeof()提供一个允许确定大小的地址。我想把这个地址传递给我的职能部门
hour = compareToLongs(&now, hourLongs, (int)(sizeof(hourLongs)/sizeof(hourLongs[0])) );
// long *, long * , int -> int
// compare time to array of times.
static int compareToLongs(long * time, long * timeList_pointer, int size){
i = 0; while (*time> (timeList_pointer)[i] && i < size){i++;}
return --i;
}
sizeof(array)
我无法将传递给sizeof()的内容传递给我的函数有什么原因吗
编辑:正如sizeof()的操作所表明的那样,可以在不发生“指针衰减”的情况下传递数组。user529758在中给出了三个示例
我想要做的应该是使用&array。当你声明一个数组时,c在后台所做的基本上就是为你想要的大小分配足够的内存,然后给你一个指针。当你说
int arr[20];
实际上,c为20个int分配了足够的内存,并给了您一个名为arr的指针(有一些区别,但为了简单起见,我用这种方式解释),因此如果函数的签名需要指向int的指针,您可以将其传递给数组
void foo(int *);
foo(arr); */ works */
这是可行的,因此不需要使用指向指针的指针,尽管您必须指定大小,因为c数组基本上只是指向某个内存的指针,因此您可以将大小作为参数接收,或者以类似于标记字符串末尾的方式标记数组的最后一个元素(使用空终止符)。
当您使用[]运算符时,c只是偏移指针并取消对它的引用,因此这两个语句是等效的(一个可读性较差)
希望这能帮助您更好地理解它,尽管我的解释有点简单。在
C
中,您无法在被调用函数中找到数组的大小。调用函数必须再传递一个参数,说明数组的大小
让我们看一些例子,看看为什么这是不可能的 首先调用函数时,您将尝试将数组作为参数传递。但是,请注意,当您将数组作为参数传递时,它会自动指向指向其元素数据类型的指针。这将阻止被调用的
函数使用sizeof
运算符计算数组大小r
比如说,
int main(void)
{
int arr_a[2] = {22, 33};
int arr_b[5] = {6, 7, 8, 9, 10};
foo(arr_a); // Here arr_a decays to an `int *`
foo(arr_b); // Here arr_b decays to an `int *` too
return 0;
}
void foo(int *arr)
{
sizeof(arr);
/* Here sizeof(arr) will always give the size of
* an `int *` which maybe 4 or 8 bytes depending
* on platform. It does not matter weather arr_a
* or arr_b was passed from main.
* And because sizeof(arr) always gives the sameresult,
* we cannot use sizeof(arr)/sizeof(arr[0]) to calculate
* the size of array that was passed.
*/
/* This value will always be the same,
* regardless of what was passed */
sizeof(arr)/sizeof(arr[0]);
}
此外,请注意:
void foo(int arr[]) { ... }
相当于:
void foo(int *arr) { ... }
编译器将静默地将int-arr[]
更改为int*arr
。因此将int-arr[]
作为参数不会有任何区别
下一步,您可以考虑传递数组的地址(通过执行&arr\u name
)。但是,请注意,&arr\u name
是指向数组的指针(具有一定的大小)
,它与指向底层数据类型的指针不同
void foo(void) {
int arr_a[2] = {22, 33};
int arr_b[3] = {7, 8, 9};
bar(&arr_a); // Note here that type of `&arr_a` is `int (*)[2]`,
// i.e. a `pointer to int array of 2 elements`, which is
// different from a `pionter to pointer to int`
bar(&arr_b); // Note here that type of `&arr_b` is `int (*)[3]`,
// i.e. a `pointer to int array of 3 elements`, which is
// different from a `int (*)[2]`,
// i.e a `pointer to int array of 2 elements`
// Note that this will give ERROR. See comments in bar()
return 0;
}
void bar(int (*arr)[2]) {
/*
* The caller of this function can ONLY pass int arrays with
* 2 elements. Caller CANNOT pass int array with 3 elemens, or
* 1 element, or 5 element.
* This means you ALWAYS KNOW the size of arrays being passed,
* and although you can calculate the size by doing
* sizeof(*arr)/sizeof(*arr[0]);
* There is no point in calculating it - you alreay know the size
*/
}
因此,基本上,您甚至不能通过传递&array\u name
来传递指向数组的指针来解决这个问题,因为您需要不同的函数来接受不同大小的数组。例如,void bar\u 2(int(*arr)[2]){…}
来接受指向2个整数数组的指针,以及void bar\u 3(int(*arr)[3]){…}
接受指向3个整数数组的指针。此外,您已经知道,在这些函数中计算大小没有意义
最后,您将尝试向指向基础数据类型的指针传递一个指针
void foo() {
int arr_a[2] = {22, 33};
int arr_b[5] = {6, 7, 8, 9, 10};
int *ptr;
ptr = &arr_a[0];
bar(&ptr); // Passing pointer to pointer to int (int **)
ptr = &arr_b[0];
bar(&ptr); // Passing pointer to pointer to int (int **)
}
void bar(int **pptr) {
sizeof(*pptr);
/* This will always be the same.
* i.e. the size of an integer pointer
* So here again you cannot use
* sizeof(*pptr)/sizeof((*pptr)[0]) to calculate the size
* as it will always give the same result */
sizeof(*pptr)/sizeof((*pptr)[0]) // Always same, no matter what was
// passed by the caller
}
您可以看到,将指针传递给指向底层数据类型的指针也不能解决此问题
因此,您可以看到,无论您做什么,在被调用函数中使用sizeof()
都无法找到数组的大小。只有在调用方传递此信息时,被调用函数才能知道数组的大小
作为旁注,代码中有一个问题
i = 0; while (now > hourLongs[i] && i < j){i++;} // AND
i = 0; while (*time> (timeList_pointer)[i] && i < size){i++;}
这是因为,您必须首先检查i
是否在数组的范围内,然后只计算hourLongs[i]
或(时间列表指针)[i]
正如其他人所说,由于数组在传递给函数时如何衰减为指向第一个元素的指针,因此无法将数组传递给函数并获取其大小。因此,需要将数组及其大小传递给函数
hour = compareToLongs(&now, hourLongs, (int)(sizeof(hourLongs)/sizeof(hourLongs[0])) );
// long *, long * , int -> int
// compare time to array of times.
static int compareToLongs(long * time, long * timeList_pointer, int size){
i = 0; while (*time> (timeList_pointer)[i] && i < size){i++;}
return --i;
}
sizeof(array)
有一种迂回的方法可以将数组传递给函数,以便获得其大小,但它仅适用于固定大小的数组
#include <stdio.h>
#include <stdlib.h>
void test1(int (*a)[10])
{
int i;
printf("size=%zu\n",sizeof(*a));
for (i=0;i<sizeof(*a)/sizeof((*a)[0]);i++) {
printf("%d\n",(*a)[i]);
}
}
int main()
{
int a[10] = {1,2,3,4,5,6,7,8,9,10};
test1(&a);
return 0;
}
#包括
#包括
无效测试1(int(*a)[10])
{
int i;
printf(“大小=%zu\n”,大小(*a));
对于(i=0;i为什么第二个被剪断的部分又失败了?这是正确的方法。唯一的一点是,我没有看到传递一个指向time
的指针的点,而不仅仅是它的值。还有..格式。不要保存在换行符上。不能直接将数组作为函数参数传递。间接传递数组的通常方法是s两个参数:第0个元素的地址和数组的长度。(在某些情况下,如果可以从数组的内容确定大小,则可以省略size参数;例如,字符串的结尾由'\0'
n指示。)
i = 0; while ( i < j && now > hourLongs[i]){i++;} // AND
i = 0; while (i < size && *time> (timeList_pointer)[i]){i++;}
#include <stdio.h>
#include <stdlib.h>
void test1(int (*a)[10])
{
int i;
printf("size=%zu\n",sizeof(*a));
for (i=0;i<sizeof(*a)/sizeof((*a)[0]);i++) {
printf("%d\n",(*a)[i]);
}
}
int main()
{
int a[10] = {1,2,3,4,5,6,7,8,9,10};
test1(&a);
return 0;
}