C 如何在不衰减的情况下将指针传递到数组,并使用';参考';在为野蛮人准备的活动中?

C 如何在不衰减的情况下将指针传递到数组,并使用';参考';在为野蛮人准备的活动中?,c,pebble-watch,pebble-sdk,C,Pebble Watch,Pebble Sdk,我读过很多关于将数组传递给函数的讨论。它们似乎是为能流利使用C语言的人编写的。我是一个还不能流利使用C语言的野蛮人 从我在其他讨论中所读到的来看,应该可以传递一个数组而不会导致指针衰减。然而,我需要帮助实现这一点。 请给我一个简洁的例子,说明如何将数组作为指针的指针传递,并确定它在传递到的函数中的大小 如果在函数中更改了数组,我希望更改数组的源。我想尽量减少额外的内存分配。 如果可能的话,我想调整函数中数组的大小。 这段代码不需要通过就可以工作 // this works j = sizeof(

我读过很多关于将数组传递给函数的讨论。它们似乎是为能流利使用C语言的人编写的。我是一个还不能流利使用C语言的野蛮人

从我在其他讨论中所读到的来看,应该可以传递一个数组而不会导致指针衰减。然而,我需要帮助实现这一点。

请给我一个简洁的例子,说明如何将数组作为指针的指针传递,并确定它在传递到的函数中的大小

如果在函数中更改了数组,我希望更改数组的源。我想尽量减少额外的内存分配。 如果可能的话,我想调整函数中数组的大小。

这段代码不需要通过就可以工作

// 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;
}