我正在创建一个已知大小的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的简单索引数组),我会得到不同的结果。
答案 0 :(得分:1)
GLuint boxArray[36];
for (GLuint i=0; i<36; i++)
{
boxArray[i] = i;
}
您指定的boxIndeciesArray
不是boxArray
,或者反过来说,因为您说第一个有效。
编辑:我看到你已经编辑了你的问题来解决这个问题,你能详细说明你如何获得你的价值观以及它为什么会起作用吗?
答案 1 :(得分:1)
您正在定义和初始化大小为36
的数组。然后打印其内容,就好像它的大小为39
一样。当然,这超出了数组的范围,并且“打印”了不存在的元素。行为未定义。超出数组范围(零或其他)的“看到”并不重要。
答案 2 :(得分:1)
就编译器而言,可能会将第二个初始化程序视为“常量”。因此,这些值被写入可执行文件的常量块,并由数组变量直接指向。
因此,以下零可能是代码中某处的另一个常量值。只要您的代码没有真正改变,编译器就会在可执行文件中将这两个值并排排列。添加更多常量可能会在将来改变这种情况。
如果你进一步查看数组的内存块,你可能会看到其他常量值(包括一些可识别的字符串)......假设你的代码足够大。
第一个初始化程序显然没有这种行为,因为内存被分配在堆栈上,并在以后填充。由于堆栈可以在每次运行程序时分配到不同的位置,因此堆栈顶部之后的值可能每次都不同。
总而言之,第二个初始化程序会使您的可执行文件变大,但启动MUCH的速度更快,因为它只是将变量指向常量。第一个初始化程序将使您的可执行文件按数组大小缩小,但在到达代码部分时动态分配内存。加上使用循环填充它将比第二个(相对)慢一点。显然36元素循环仍然是超快速的,但简单的指针分配是更少的循环。
答案 3 :(得分:0)
它们应该是等价的,我能想到你为什么会有超出数组末尾的值的唯一原因是因为你在用你检查数组的代码中超出界限。
使用以下代码检查数组:
for (int i = 0; i < 36; i++)
printf("%d: %d\n", i, boxArray[i]);
你应该看到它们确实是等同的。
编辑你不能越界,调用未定义的行为 - 任何事情都可能发生。