C语言 如何获取传递给函数的数组的大小?

sc4hvdpw  于 2023-05-28  发布在  其他
关注(0)|答案(8)|浏览(545)

我试图写一个函数,打印出数组中的元素。但是,当我处理传递的数组时,我不知道如何迭代数组。

void
print_array(int* b)
{
  int sizeof_b = sizeof(b) / sizeof(b[0]);
  int i;
  for (i = 0; i < sizeof_b; i++)
    {
      printf("%d", b[i]);
    }
}

迭代传递的数组的最佳方法是什么?

k5ifujac

k5ifujac1#

您还需要将数组的大小传递给函数。
当你把数组传递给函数时,你实际上是在传递数组中第一个元素的地址。所以指针只在函数内部指向第一个元素一次。
由于数组中的内存是连续的,因此仍然可以使用指针算法(如(b+1))来指向第二个元素或等效的b[1]

void print_array(int* b, int num_elements)
{
  for (int i = 0; i < num_elements; i++)
    {
      printf("%d", b[i]);
    }
}

这个技巧只适用于数组,而不适用于指针:

sizeof(b) / sizeof(b[0])

arrays are not the same as pointers

uqjltbpv

uqjltbpv2#

为什么不使用函数模板(C++)?

template<class T, int N> void f(T (&r)[N]){
}

int main(){
    int buf[10];
    f(buf);
}

编辑2:
qn现在看起来有C标记,C++标记被删除。

cx6n0qe3

cx6n0qe33#

对于C,你必须传递数组的长度(元素的数量)。
对于C++,你可以传递长度,但是,如果你可以访问C++0x,最好使用std::array。参见herehere。它携带长度,并在使用at()成员函数访问元素时提供越界检查。

hgc7kmma

hgc7kmma4#

C99中,你可以要求一个数组至少有n个元素:

void print_array(int b[static n]);

6.7.5.3.7:将参数声明为“array of type”应调整为“qualified pointer to type”,其中类型限定符(如果有的话)是在数组类型派生的[ and ]中指定的。如果关键字static也出现在数组类型派生的[ and ]中,则对于每个函数调用,相应的实际参数的值应提供对数组的第一个元素的访问,该数组至少具有与size表达式指定的元素一样多的元素。
在GCC中,你可以像这样pass the size of an array implicitly

void print_array(int n, int b[n]);
bhmjp9jg

bhmjp9jg5#

你可以试试这个。。

#include <cstdio>                                                               

void 
print_array(int b[], size_t N) 
{ 
    for (int i = 0; i < N; ++i) 
        printf("%d ", b[i]);
    printf("\n");
}

template <size_t N>
inline void 
print_array(int (&b)[N]) 
{
    // could have loop here, but inline forwarding to
    // single function eliminates code bloat...
    print_array(b, N);
}                                                                                

int main()                                                                      
{                                                                               
    int a[] = { 1, 2 };                                                         
    int b[] = { };
    int c[] = { 1, 2, 3, 4, 5 };                                                

    print_array(a);                                                             
    // print_array(b);                                                          
    print_array(c);                                                             
}

有趣的是,B不工作。

array_size.cc: In function `int main()':
array_size.cc:19: error: no matching function for call to `print_array(int[0u])'

JoshD在下面的评论中指出了大小为0的数组(GCC扩展)的问题,以及上面的大小推断。

ygya80vv

ygya80vv6#

在c中,你也可以使用某种类型的列表类,它被实现为一个带有size方法的数组或一个带有size成员的结构(在c或c中)。

1szpjjfi

1szpjjfi7#

使用变量传递数组的大小。int sizeof_b = sizeof(b) / sizeof(b[0]);除了获取预先声明的数组大小外什么都不做,数组大小是已知的,你可以把它作为参数传递;例如void print_array(int*b, int size)size也可以是用户定义的大小。

  • int sizeof_b = sizeof(b) / sizeof(b[0]);会在元素数量小于预先声明的array-size时导致冗余迭代。*
xpcnnkqh

xpcnnkqh8#

这个问题已经有了一些很好的答案,例如the second one。然而,由于缺乏解释,因此我想扩展示例并解释它:
使用模板和模板参数(在本例中为None-Type Template parameters)可以获得任何类型的固定数组的大小。
假设你有这样一个函数模板:

template<typename T, int S>
int getSizeOfArray(T (&arr)[S]) {
    return S;
}

该模板显然适用于任何类型(这里是T)和固定整数(S)。如你所见,函数接受了一个对T* 类型的S对象数组的引用,正如你所知道的,在C++中,你不能通过值来传递数组,而是通过引用来传递数组,所以函数必须接受一个引用。
如果你这样使用它:

int i_arr[] = { 3, 8, 90, -1 };
std::cout << "number f elements in Array: " << getSizeOfArray(i_arr) << std::endl;

编译器将隐式地示例化模板函数并检测参数,因此这里的S是4,它被返回并打印到输出。

相关问题