从函数中获取数组的计数

时间:2017-12-29 10:19:10

标签: c arrays pointers parameter-passing sizeof

我正在尝试编写一个打印给定数组元素的函数。但是,我不明白我如何计算传递给我的函数的数组元素。这是代码:

在这个例子中,我试图从我的函数中获取计数,尽管这只返回1.

#include <stdio.h>

void first_function(int ages[], char *names[]) {
    int i = 0;
    int count = sizeof(*ages) / sizeof(int);
    for(i = 0; i < count; i++) {
        printf("%s has lived %d years.\n", names[i], ages[i]);
    }
}

int main(int argc, char *argv[])
{
    int ages[] = { 7, 32, 36 };
    char  *names[] = {
        "Tiger", "Sandy",
        "Ryan"
    };

    first_function(ages, names);
    printf("---\n");

    return 0;

}

在这个例子中,我给函数一个额外的参数(count),然后从main中获取计数。这是正常的做法吗?看起来不洁净。

#include <stdio.h>

void first_function(int ages[], char *names[], int count) {
    int i = 0;
    for(i = 0; i < count; i++) {
        printf("%s has lived %d years.\n", names[i], ages[i]);
    }
}

int main(int argc, char *argv[])
{
    int ages[] = { 7, 32, 36 };
    char  *names[] = {
        "Tiger", "Sandy",
        "Ryan"
    };

    int count = sizeof(ages) / sizeof(int);

    first_function(ages, names, count);
    printf("---\n");

    return 0;

}

3 个答案:

答案 0 :(得分:5)

你所谓的不洁方式是正常的方式。 (如果数组参数已衰减为指针类型,则sizeof惯用法不起作用。虽然考虑使用size_t类型进行统计,但不是int

另一种方法是使用特定值来表示数组的结尾。实际上这就是字符串库函数在C中的工作方式;用NUL发信号通知字符串的结尾。

答案 1 :(得分:5)

根据C标准(6.7.6.3函数声明符(包括原型))

  

7 应调整参数声明为''类型数组''   ''限定指向类型'',其中类型限定符(如果有)   是在数组类型的[和]内指定的那些   推导....

所以这个函数声明

void first_function(int ages[], char *names[]);
调整声明为数组的相应参数后,

等效于以下声明。

void first_function( int *ages, char **names );

即参数agesnames在函数中具有指针类型。 结果这个表达

int count = sizeof(*ages) / sizeof(int);

(我想你的意思是

int count = sizeof(ages) / sizeof(int);
                   ^^^^

尽管如此)

相当于

int count = sizeof( int) / sizeof(int);

因为子表达式*ages的类型是int。

如果您要编写像

这样的表达式
int count = sizeof(ages) / sizeof(int);

然后它相当于

int count = sizeof(int *) / sizeof(int);

并且再次不会产生作为参数传递的数组的大小。

对于没有sentinel值的此类数组,如果需要,还必须将其大小传递给函数。

因此该函数应该声明为

void first_function(int ages[], char *names[], size_t n);

并调用

size_t count = sizeof(ages) / sizeof(*ages);

first_function(ages, names, count);

注意不需要在函数内初始化变量i两次。该功能可以看起来像

void first_function(int ages[], char *names[], size_t count) 
{
    for ( size_t i = 0; i < count; i++) 
    {
        printf("%s has lived %d years.\n", names[i], ages[i]);
    }
}

答案 2 :(得分:3)

是的,你不能在这里使用sizeof来获取被调用函数中数组的长度。因为数组在被调用函数中衰减为指针。这就是为什么它会返回sizeof指针而不是数组的大小。

解决方案 - 您需要传递指定数组大小的另一个参数,或者保留像NULL这样的占位符或某个值来标记数组的结尾。 (嗯,你已经在你的第二个解决方案中遵循了 - 这非常好,并且它可以正常工作)。

sizeof的返回值为size_t。使用size_t代替int。  这是处理sizeof运算符返回的正确方法。