正确计算C中数组中字符串元素数的方法

时间:2014-12-28 00:04:47

标签: c arrays count segmentation-fault sizeof

这是我一直在喋喋不休的代码。

#include <stdio.h>

int main(int argc, char *argv[])
{
    int i=0;

    for(i=1;i<argc;i++){
        printf("arg %i: %s\n", i , argv[i]);
    }

    //custom array of strings
    char *states[] = {
                "California", "Oregon", "Idaho", "Arkansas", "Washington",
                "Texas", "Montana"
    };
    int num_states = sizeof(*states)-1;
    printf("%i\n", num_states);
    for(i=0;i<num_states;i++){
        printf("state %i: %s\n", i, states[i]);

    }

    return 0;
}

我的问题是一个相当简单的问题,在我完成这项工作之前,我遇到了一个非常令人沮丧的段错误。

&#34; int num_states = sizeof(*states)-1;&#34;这行可以返回数组中字符串的数量减一(不知道为什么需要-1来防止段错误)

&#34; int num_states = sizeof(states);&#34;这返回了56,并导致我的for循环遍历那些不存在的东西。

问题是我不确定区别是什么。我最好的猜测是,第一行计算states[]组成的总字节数,第二行计算*states存储的内存中的位置数。

如果我的想法错了,请纠正我。如果你能告诉我为什么-1以某种方式阻止了这一段错误,我会很感激。

1 个答案:

答案 0 :(得分:3)

正确的方法

num_states中的值应为:

int num_states = sizeof(states) / sizeof(states[0]);

也就是说,数组中元素的数量是数组的大小除以数组的第0个元素的大小(与数组的每个其他元素的大小相同)。

这可以推广到处理其他数组。回到Fortran和/或Basic,我经常使用宏:

#define DIM(x) (sizeof(x)/sizeof(*(x)))

注意:这仅适用于已知大小的数组。它不适用于&#39;数组&#39;传递到功能;这样的阵列&#39;堕落到指针,你最终得到了错误的答案。如果您在当前源文件(任何函数之外)或当前函数中定义了该函数,则可以安全地使用它。

为什么您的代码有效

至于为什么你的例子有效 - 答案是巧合&#39;。这取决于以下事实:

  • 您的数组有7个元素。
  • 系统上指针的大小为8个字节。

sizeof(*states)的值为8,因为*stateschar *并且(在您的64位计算机上),指针的大小为8.因此int num_states = sizeof(*states)-1; &#39;工作&#39;碰巧。如果您在数组中添加或删除了任何条目,或者在32位计算机上编译了代码,那么它将再次失败(确切的失败模式取决于环境的变化),而计算元素的数量如图所示无论这些变化如何,都能正常工作。