这是我一直在喋喋不休的代码。
#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以某种方式阻止了这一段错误,我会很感激。
答案 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;。这取决于以下事实:
sizeof(*states)
的值为8,因为*states
是char *
并且(在您的64位计算机上),指针的大小为8.因此int num_states = sizeof(*states)-1;
&#39;工作&#39;碰巧。如果您在数组中添加或删除了任何条目,或者在32位计算机上编译了代码,那么它将再次失败(确切的失败模式取决于环境的变化),而计算元素的数量如图所示无论这些变化如何,都能正常工作。