int * vs int []与int(*)[]在函数参数中。我应该使用哪一个? [英] int * vs int [] vs int (*)[] in function parameters. Which one should I use?

查看:154
本文介绍了int * vs int []与int(*)[]在函数参数中。我应该使用哪一个?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在C语言中,有许多不同的方法来声明一个函数的参数,它将一个数组作为通过指针传递的参数。



我有准备了一个例子,向你展示我的意思。它是C ++中 std :: accumulate 函数的一个实现。它是一个函数,可以添加数组中的所有元素并返回结果。



我可以这样写:

  int accumulate(int n,int * array)
{
int i;
int sum = 0;
for(i = 0; i< n; ++ i){
sum + = array [i];
}
回报金额;
}

也可以这样写(这意味着完全相同的东西):

  int accumulate(int n,int array [])
{
int i;
int sum = 0;
for(i = 0; i< n; ++ i){
sum + = array [i];
}
回报金额;
}

我也可以这样写:

  int accumulate(int n,int(* array)[])
{
int i;
int sum = 0;
for(i = 0; i sum + =(* array)[i];
}
回报金额;





$ b

所有这些选项都非常相似,并生成相同的可执行代码,但它们具有这是调用者如何传递参数的细​​微差别。



这是前两个版本被调用的方式:

  int main(void)
{
int a [] = {3,4,2,4,6,1,-40,23,35};
printf(%d\\\
,accumulate(ARRAY_LENGTH(a),a));
返回0;

$ / code>

这是第三版的调用方式:

  int main(void)
{
int a [] = {3,4,2,4,6,1, - 40,23,35};
printf(%d \ n,accumulate(ARRAY_LENGTH(a),& a));
返回0;
}

请注意,第三个选项需要用户明确指定 a & a 。前两个选项并不要求这样做,因为数组会隐式转换为指向C中相同类型的指针。



我始终偏好第三种方法。 b
$ b

这就是为什么:


  • 它与其他类型的传递方式更一致指针。

      int draw_point(struct point * p); 

    int main()
    {
    struct point p = {3,4};
    draw_point(& p); //这里是所需操作员的'地址'。
    }


  • 它可以使用像 ARRAY_LENGTH 来获取数组元素的数量。

      #include  ; 
    #define ARRAY_LENGTH(A)(sizeof(A)/ sizeof(A [0]))

    void this_works(int(* array)[10])
    {
    / *这工作! * /
    printf(%d \ n,ARRAY_LENGTH(* array));
    }

    void this_is_invalid_and_dangerous(int array [10])
    {
    / *这不起作用,因为`array`实际上是一个指针。 * /
    printf(%d \ n,ARRAY_LENGTH(array));

    code $

    $ b $ p <参见 int(* array)中的 int array [] (和 int * array ) [] 是你可以写数组[X] 而不是(* array)[X] 当你想抓住一个索引。



    但是因为我不是专业人士,我会问你喜欢哪个版本。

    你什么时候用什么?

    我主要使用 int(* array)[N] ,但是我发现其他两种方法也很常见。

    解决方案

    参数 int array [] int * array 是相同的。你也可以使用。这是味道的问题。 int(* array)[] 是单调乏味的,并没有被广泛使用。

    当2D数组传递给函数时,int(* array)[n] 用得最广泛。在这种情况下,你可以以 array [i] [j] 的形式访问数组元素。


    In the C-programming language there are many different ways to declare the parameter of a function that takes an array as an argument passed through a pointer.

    I have prepared an example that shows you what I mean. It is an implementation of the std::accumulate function in C++. It is a function that performes addition of all elements in an array and returns the result.

    I can write it like this:

    int accumulate(int n, int *array)
    {
        int i;
        int sum = 0;
        for (i = 0; i < n; ++i) {
            sum += array[i];
        }
        return sum;
    }
    

    This can also be written to this (which means the exact same thing):

    int accumulate(int n, int array[])
    {
        int i;
        int sum = 0;
        for (i = 0; i < n; ++i) {
            sum += array[i];
        }
        return sum;
    }
    

    I can also write it like this:

    int accumulate(int n, int (*array)[])
    {
        int i;
        int sum = 0;
        for (i = 0; i < n; ++i) {
            sum += (*array)[i];
        }
        return sum;
    }
    

    All these options are very similar and generate the same executable code but they have a slight difference which is how the caller passes the arguments.

    This is how the first two versions gets called:

    int main(void)
    {
        int a[] = {3, 4, 2, 4, 6, 1, -40, 23, 35};
        printf("%d\n", accumulate(ARRAY_LENGTH(a), a));
        return 0;
    }
    

    This is how the thrid version gets called:

    int main(void)
    {
        int a[] = {3, 4, 2, 4, 6, 1, -40, 23, 35};
        printf("%d\n", accumulate(ARRAY_LENGTH(a), &a));
        return 0;
    }
    

    Note that the third option requires to user to explicitly specify the address of a with &a. The first two options does not require this because arrays implicitly gets converted into pointers to the same type in C.

    I have always preferred the third approach.

    This is why:

    • It is more consistent with how other types are passed by pointers.

      int draw_point(struct point *p);
      
      int main()
      {
          struct point p = {3, 4};
          draw_point(&p); // Here is the 'address of' operator required.
      }
      

    • It makes it possible to use macros like ARRAY_LENGTH to get the amount of elements in the array.

      #include <stdio.h>
      #define ARRAY_LENGTH(A) (sizeof(A) / sizeof(A[0]))
      
      void this_works(int (*array)[10])
      {
          /* This works! */
          printf("%d\n", ARRAY_LENGTH(*array));
      }
      
      void this_is_invalid_and_dangerous(int array[10])
      {
          /* This does NOT work because `array` is actually a pointer. */
          printf("%d\n", ARRAY_LENGTH(array));
      }
      

    The only advantage I see with int array[] (and int *array) over int (*array)[] is that you get to write array[X] instead of (*array)[X] when you wish to grab an index.

    But because I am not a professional I will ask you which version you prefer.

    When do you use what? What are the reasons to choose one of these options over another?

    I have mostly used int (*array)[N] but I see that the other two approaches are quite common as well.

    解决方案

    When used as function parameters, int array[] and int *array are same. You can use either. It is matter of taste. int (*array)[] is tedious and not used widely.

    int (*array)[n] is used most widely when 2D array is passed to a function. In that case you can access the element of array as array[i][j].

    这篇关于int * vs int []与int(*)[]在函数参数中。我应该使用哪一个?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆