是什么意思有阵列与功能尺寸参数
只见那看起来是这样的是什么意思有阵列与功能尺寸参数
int foo(int array[100]) {
...
}
的功能是如何从
int foo(int *array)
此不同的是,它有什么不同?
在哪些地方应该/可以使用前一种方法。
回答:
它们在功能上是相同的。您应该使用第二种方法并传递数组长度为的参数。
否则,你就是自找麻烦:
// this will compile without warning, even if using -Wall int myArray[50] = {0};
foo(myArray);
如果foo()
假设数组实际上是100个元素长,它会溢出的阵列。
更好的办法:
int foo(int *array, size_t array_len) { // do stuff
}
更妙的是,使用vector
,携带它的大小与它可以超越矢量结束不(正常情况下)访问:
int foo(const std::vector<int>& array) { // do stuff
}
回答:
与此声明无区别
int foo(int array[100]) //1 int foo(int array[]) //2
int foo(int *array) //3
如果函数可以承担固定大小的数组,在这种情况下,100个元素,1版本更清楚程序员使用此功能。在所有其他情况下 - 3是不错的选择
回答:
没什么,他们以相同的方式工作。这里一个简单的例子:
int WithArray(int array[10]) {
return array[1] + array[2]; // breakpoint 1
}
int WithPointer(int *pointer)
{
return *(pointer + 1) + *(pointer + 2); // breakpoint 2
}
void main()
{
int array[] = {0,1,2,3,4,5,6,7,8,9};
int b = WithPointer(array);
int a = WithArray(array);
printf("a = %d\nb = %d\n", a, b);
}
好吧,我会先请WithPointer(),以防万一WIthArray()复制堆栈上的数组。 这里的所述堆叠中的第二个断点:
Breakpoint 2, WithPointer (pointer=0xbffff418) at prova.c:10 10 return *(pointer + 1) + *(pointer + 2);
(gdb) x/20x ($esp - 8)
0xbffff404: 0x08049ff4 0xbffff418 0xbffff448 0x0804843b
0xbffff414: 0xbffff418 0x00000000 0x00000001 0x00000002
0xbffff424: 0x00000003 0x00000004 0x00000005 0x00000006
0xbffff434: 0x00000007 0x00000008 0x00000009 0x08048460
0xbffff444: 0x00000000 0xbffff4c8 0x00144bd6 0x00000001
正如预期的那样,有我们的指针(0xbffff418,在第二行的第一个值),并且右后,阵列[](这是对主()” s堆栈帧)。 让我们来看看里面WithArray()堆栈:
(gdb) continue Continuing.
Breakpoint 1, WithArray (array=0xbffff418) at prova.c:5
5 return array[1] + array[2];
(gdb) x/20x ($esp - 8)
0xbffff404: 0x08049ff4 0xbffff418 0xbffff448 0x08048449
0xbffff414: 0xbffff418 0x00000000 0x00000001 0x00000002
0xbffff424: 0x00000003 0x00000004 0x00000005 0x00000006
0xbffff434: 0x00000007 0x00000008 0x00000009 0x08048460
0xbffff444: 0x00000003 0xbffff4c8 0x00144bd6 0x00000001
完全一样的东西!所以他们如何传递给函数没有区别。并且它们也以相同的方式处理,请看:
(gdb) disass WithPointer Dump of assembler code for function WithPointer:
0x080483cc <+0>: push %ebp
0x080483cd <+1>: mov %esp,%ebp
0x080483cf <+3>: mov 0x8(%ebp),%eax # get base address
0x080483d2 <+6>: add $0x4,%eax # compute offset
0x080483d5 <+9>: mov (%eax),%edx # dereference and get val.
0x080483d7 <+11>: mov 0x8(%ebp),%eax # base address
0x080483da <+14>: add $0x8,%eax # offset (2 * sizeof(int))
0x080483dd <+17>: mov (%eax),%eax # get *eax
0x080483df <+19>: lea (%edx,%eax,1),%eax # tricky way to add them
0x080483e2 <+22>: pop %ebp
0x080483e3 <+23>: ret
End of assembler dump.
(gdb) disass WithArray
Dump of assembler code for function WithArray:
0x080483b4 <+0>: push %ebp
0x080483b5 <+1>: mov %esp,%ebp
0x080483b7 <+3>: mov 0x8(%ebp),%eax # first element of array
0x080483ba <+6>: add $0x4,%eax # move to the second
0x080483bd <+9>: mov (%eax),%edx # and get its value
0x080483bf <+11>: mov 0x8(%ebp),%eax # base of array
0x080483c2 <+14>: add $0x8,%eax # compute address of second
0x080483c5 <+17>: mov (%eax),%eax # element and get load it
0x080483c7 <+19>: lea (%edx,%eax,1),%eax # compute sum
0x080483ca <+22>: pop %ebp
0x080483cb <+23>: ret
End of assembler dump.
代码是相同的。请注意,该数组是作为指针处理的。
回答:
在C++中,不能将数组作为参数传递给函数。根据§8.3.5至pointer to T
转换展示array of T
类型参数的函数声明。这意味着下面的声明是完全等价的:
void f(int a[10]); void f(int a[]);
void f(int *a);
所以,事实上,正如你指出他们是完全等价的,即使第一个可能会误导开发商阅读代码的编译器,作为给定大小在声明中不会被强制执行。
这是为了那些reference to array of T
类型,其中说法也不衰减的指针的函数参数的不同,而是保持了完整的类型:
void f(int (&a)[10]); // takes an array of exactly 10 integers
在这种情况下,编译器将实际强制执行引用的类型,即array of 10 int
(包括大小)。函数内部的代码可以假设总是有10个元素,编译器会确保这一点。
§8.3.5[dcl.fct]/3
[...]确定每个参数的类型,类型的任何参数“阵列T的”或后“函数返回T”是调整为“指向T的指针”或“指向函数返回T的指针”。[...]
以上是 是什么意思有阵列与功能尺寸参数 的全部内容, 来源链接: utcz.com/qa/262061.html