2

我正在创建一个C永远不会改变的已知大小的数组。以下两个初始化器有什么区别?

1.

GLuint boxArray[36];
for (GLuint i=0; i<36; i++) 
{
    boxArray[i] = i;
}

2.

GLuint boxArray[] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35};

当我换出上面的两种方法时,只有第一种在我的代码中有效。检查数组本身看起来非常相似(唯一的区别是第二种方法的两个元素 PAST 数组末尾的值为零)。

我正在使用以下代码在创建数组后检查它...

for (int j=0; j<39; j++) {
    NSLog(@"boxArray[%d] = %d", j, boxArray[j]);
 }

两个输出都是相同的,只是上面的细微差别。我故意写到数组的末尾以检查那里的差异。

然后我将数组填充到一个 NSData 对象中,该对象是该代码所在的对象的实例变量......就像这样......

_boxArrayData  = [NSData dataWithBytes:boxArray length:sizeof(boxArray)];

当我从 NSData 对象中提取数据时,我可以检查另一端的数据,并且它在那里看起来也一样。但是,当我使用数据(它是 OpenGLES2.0 的简单索引数组)时,我会得到不同的结果。

4

4 回答 4

1
GLuint boxArray[36];
for (GLuint i=0; i<36; i++) 
{
    boxArray[i] = i;
}

你的分配boxIndeciesArray不是boxArray,或者反之亦然,因为你说第一个有效。

编辑:我看到你已经编辑了你的问题来解决这个问题,你能否详细说明你如何获得你的价值观以及它为什么不起作用?

于 2013-06-07T02:54:26.973 回答
1

您正在定义和初始化一个 size 数组36。然后你打印它的内容,就好像它有 size 一样39。当然,这超出了数组的范围,并“打印”了不存在的元素。行为未定义。您在数组边界之外“看到”的内容(零或其他内容)并不重要。

于 2013-06-07T03:43:03.700 回答
1

就编译器而言,第二个初始化程序可能被视为“常量”。因此,这些值被写入可执行文件的常量块并由数组变量直接指向。

因此,以下零可能是代码中某处的另一个常量值。只要您的代码没有真正改变,编译器就会在可执行文件中并排排列这两个值。添加更多常量可能会在未来改变这一点。

如果您进一步查看数组的内存块,您可能会看到其他常量值(包括一些可识别的字符串)......假设您的代码足够多。

第一个初始化程序显然没有这种行为,因为内存是在堆栈上分配的,然后再填充。由于每次运行程序时都可以将堆栈分配在不同的位置,因此每次堆栈顶部之后的值都可能不同。

所以总而言之,第二个初始化程序使您的可执行文件更大,但启动速度更快,因为它只是将您的变量指向一个常量。第一个初始化程序将使您的可执行文件按数组大小缩小,但在您到达代码的那部分时动态分配内存。加上使用循环来填充它会比第二个慢一吨(相比之下)。显然 36 个元素的循环仍然非常快,但简单的指针分配循环次数要少得多。

于 2013-06-07T04:32:24.273 回答
0

它们应该是等价的,我能想到的为什么你的值会超过数组末尾的唯一原因是因为你在检查数组的代码中超出了界限。

使用如下代码检查数组:

for (int i = 0; i < 36; i++)
    printf("%d: %d\n", i, boxArray[i]);

您应该看到它们确实是等价的。

编辑您不能越界,这会调用未定义的行为-任何事情都可能发生。

于 2013-06-07T02:51:30.693 回答