6 回答
TA贡献1784条经验 获得超7个赞
据说数组“衰变”成指针。声明为int numbers [5]无法重新指向的C ++数组,即你不能说numbers = 0x5a5aff23。更重要的是,衰变一词意味着类型和维度的损失; 通过丢失维度信息(计数5)而numbers衰减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信息,而第一个将不会,因为数组参数已经衰减分配给参数。
1在编译时应该知道常量U.
TA贡献1876条经验 获得超6个赞
数组与C / C ++中的指针基本相同,但并不完全相同。转换数组后:
const int a[] = { 2, 3, 5, 7, 11 };
到一个指针(没有强制转换,因此在某些情况下可能会意外发生):
const int* p = a;
你失去了sizeof操作员计算数组中元素的能力:
assert( sizeof(p) != sizeof(a) ); // sizes are not equal
这种丧失的能力被称为“衰变”。
有关更多详细信息,请查看有关数组衰减的文章。
TA贡献1898条经验 获得超8个赞
这是标准所说的(C99 6.3.2.1/3 - 其他操作数 - 左值,数组和函数指示符):
除非它是sizeof运算符或一元&运算符的操作数,或者是用于初始化数组的字符串文字,否则将类型为''array of type''的表达式转换为类型为''指针的表达式type''指向数组对象的初始元素,而不是左值。
这意味着几乎在表达式中使用数组名称的任何时候,它都会自动转换为指向数组中第1项的指针。
请注意,函数名称以类似的方式起作用,但函数指针的使用要少得多,而且使用方式更加专业,因为它不会引起与将数组名称自动转换为指针一样多的混淆。
C ++标准(4.2数组到指针转换)将转换要求放宽到(强调我的):
左值或类型“数组NT的”或“结合的T未知的数组”的右值可以被转换成类型的右值“指针T.”
所以转换不会有发生像它几乎总是用C做(这让对数组类型函数重载或模板匹配)。
这也是为什么在C中你应该避免在函数原型/定义中使用数组参数(在我看来 - 我不确定是否有任何普遍的协议)。它们引起混淆并且无论如何都是虚构的 - 使用指针参数并且混淆可能不会完全消失,但至少参数声明不是说谎。
TA贡献1821条经验 获得超4个赞
“Decay”是指表达式从数组类型到指针类型的隐式转换。在大多数情况下,当编译器看到数组表达式时,它将表达式的类型从“N元素数组T”转换为“指向T”,并将表达式的值设置为数组第一个元素的地址。此规则的例外情况是,数组是sizeof或&运算符的操作数,或者数组是在声明中用作初始值设定项的字符串文字。
假设以下代码:
char a[80];
strcpy(a, "This is a test");
表达式a的类型为“80元素的char数组”,表达式“This is a test”的类型为“16元素的char数组”(在C中;在C ++中,字符串文字是const char的数组)。但是,在调用中strcpy(),表达式都不是sizeof或的操作数&,因此它们的类型被隐式转换为“指向char的指针”,并且它们的值被设置为每个中的第一个元素的地址。什么strcpy()接收不是数组,但是指针,作为其原型看出:
char *strcpy(char *dest, const char *src);
这与数组指针不同。例如:
char a[80];
char *ptr_to_first_element = a;
char (*ptr_to_array)[80] = &a;
双方ptr_to_first_element并ptr_to_array具有相同的价值 ; a的基地址。但是,它们是不同的类型,并且处理方式不同,如下所示:
a[i] == ptr_to_first_element[i] == (*ptr_to_array)[i] != *ptr_to_array[i] != ptr_to_array[i]
请记住,表达a[i]被解释为*(a+i)(如果该数组类型转换为指针类型仅作品),所以无论a[i]和ptr_to_first_element[i]工作相同。表达式(*ptr_to_array)[i]被解释为*(*a+i)。表达*ptr_to_array[i]和ptr_to_array[i]可能导致的编译器警告或者根据上下文的错误; 如果你期望他们评价,他们肯定会做错事a[i]。
sizeof a == sizeof *ptr_to_array == 80
同样,当数组是操作数时sizeof,它不会转换为指针类型。
sizeof *ptr_to_first_element == sizeof (char) == 1
sizeof ptr_to_first_element == sizeof (char *) == whatever the pointer size
is on your platform
ptr_to_first_element 是一个指向char的简单指针。
TA贡献1893条经验 获得超10个赞
C中的数组没有任何价值。
只要对象的值是预期的但对象是数组,则使用其第一个元素的地址来代替类型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运算符的操作数,或者是&运算符('运算符的地址),或者是用于初始化字符数组的字符串文字。
TA贡献1864条经验 获得超6个赞
当阵列腐烂并被指向时;-)
实际上,只是如果你想在某个地方传递一个数组,而是传递指针(因为谁将为你传递整个数组),人们会说可怜的数组衰减到指针。
- 6 回答
- 0 关注
- 736 浏览
添加回答
举报