什么是阵列的衰减? 与数组指针有关系吗?
#1楼
当数组腐烂并指向;-)时
实际上,只是如果您想在某个地方传递一个数组,但是要传递指针(因为谁会为您传递整个数组),人们说可怜的数组会退化为指针。
#2楼
据说数组会“衰减”到指针中。 声明为int numbers [5]
的C ++数组无法重新指向,即,您不能说numbers = 0x5a5aff23
。 更重要的是,术语“衰减”表示类型和尺寸的损失。 numbers
由于丢失尺寸信息(计数5)而衰减为int*
,并且类型不再是int [5]
。 在这里寻找不发生衰减的情况 。
如果要按值传递数组,则实际上是在复制指针-将指向数组第一个元素的指针复制到参数(其类型也应该是数组元素类型的指针)。 这是由于数组的衰减性质而起作用的。 一旦衰减, sizeof
不再给出完整数组的大小,因为它实际上变成了指针。 这就是为什么(除其他原因外)首选通过引用或指针传递。
传递数组1的三种方法:
void by_value(const T* array) // const T array[] means the same
void by_pointer(const T (*array)[U])
void by_reference(const T (&array)[U])
最后两个将提供适当的sizeof
信息,而第一个将不提供信息,因为array参数已衰减为可分配给该参数。
1常数U在编译时应该是已知的。
#3楼
数组与C / C ++中的指针基本相同,但不完全相同。 转换数组后:
const int a[] = { 2, 3, 5, 7, 11 };
转换为指针(无需强制转换即可工作,因此在某些情况下可能会意外发生):
const int* p = a;
您将失去sizeof
运算符对数组中元素进行计数的能力:
assert( sizeof(p) != sizeof(a) ); // sizes are not equal
这种丧失的能力称为“衰变”。
有关更多详细信息,请查看有关数组衰减的本文 。
#4楼
数组衰减意味着,当数组作为参数传递给函数时,将其等同于指针(“衰减至”)。
void do_something(int *array) {
// We don't know how big array is here, because it's decayed to a pointer.
printf("%i\n", sizeof(array)); // always prints 4 on a 32-bit machine
}
int main (int argc, char **argv) {
int a[10];
int b[20];
int *c;
printf("%zu\n", sizeof(a)); //prints 40 on a 32-bit machine
printf("%zu\n", sizeof(b)); //prints 80 on a 32-bit machine
printf("%zu\n", sizeof(c)); //prints 4 on a 32-bit machine
do_something(a);
do_something(b);
do_something(c);
}
上面有两个并发症或例外。
首先,在C和C ++中处理多维数组时,仅丢失第一维。 这是因为数组在内存中是连续布置的,所以编译器必须知道除第一个维以外的所有维,以便能够计算到该内存块的偏移量。
void do_something(int array[][10])
{
// We don't know how big the first dimension is.
}
int main(int argc, char *argv[]) {
int a[5][10];
int b[20][10];
do_something(a);
do_something(b);
return 0;
}
其次,在C ++中,您可以使用模板来推断数组的大小。 Microsoft将它用于诸如strcpy_s之类的Secure CRT函数的C ++版本,并且您可以使用类似的技巧来可靠地获取数组中的元素数 。
#5楼
C语言中的数组没有任何价值。
无论何时需要对象的值但该对象是一个数组,都将使用其第一个元素的地址,并使用pointer to (type of array elements)
类型pointer to (type of array elements)
。
在函数中,所有参数均按值传递(数组也不例外)。 当您在函数中传递数组时,它“分解为指针”(原文如此); 当您将数组与其他数组进行比较时,它再次“衰减为指针”(原文如此); ...
void foo(int arr[]);
函数foo需要一个数组的值。 但是,在C语言中,数组没有任何价值! 因此foo
取而代之的是数组第一个元素的地址。
int arr[5];
int *ip = &(arr[1]);
if (arr == ip) { /* something; */ }
在上面的比较中, arr
没有值,因此它成为一个指针。 它成为指向int的指针。 该指针可以与变量ip
进行比较。
再次使用数组索引语法,您会看到arr被“分解为指针”
arr[42];
/* same as *(arr + 42); */
/* same as *(&(arr[0]) + 42); */
数组只有当它是sizeof运算符的操作数或&运算符(“ address of”运算符的地址)或用作初始化字符数组的字符串文字时,才不会衰减为指针。
来源:oschina
链接:https://my.oschina.net/stackoom/blog/3171724