什么是阵列衰减?

爷,独闯天下 提交于 2020-02-27 15:04:53

什么是阵列的衰减? 与数组指针有关系吗?


#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”运算符的地址)或用作初始化字符数组的字符串文字时,才不会衰减为指针。

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!