我在使用c编译时发现了一个区别,而我在c ++中编译时我并不完全理解......假设我声明了一个大小为5的字符数组:
char my_array[5];
根据我的理解," my_array"实际上是一个char指针,它允许我这样做:
char* a = my_array;
现在,我明白当我声明我的数组时,我只分配了5个字节(每个值分配一个),这意味着"& my_array"不应该存在,因为没有为my_array指针分配内存。为了证明这一点,我这样做了:
char* b = &my_array; // compiler error in c++, not in c
char** c = &my_array; // compiler error in c++, not in c
我没有区别,为什么会允许这样做?不过,让我们说我想将我的char [5]转换为char *,而不使用a的方法,我发现我也可以这样做:
char* c = (char*)&my_array; // works both in c and c++
我真的不明白。我没有确定"& my_array"不存在?更令人担忧的是,这两行返回了相同的确切值:
// a and c have the same value (both in c and c++)
char* a = my_array;
char* c = (char*)&my_array;
接下来,让我们说我想在运行时执行这5个字节,所以我声明了一个新类型:
// pFunc is a pointer to function returning void
typedef void (*pFunc)();
然后我尝试声明一个指向函数的指针,该指针将执行我的字节数组:
pFunc pFunc1 = (pFunc)&my_array; // works, but I don't really understand why
pFunc pFunc2 = (pFunc)my_array; // compiler error in c++, not in c
突然间,& my_array不仅编译没有问题,而且它也是使用c ++(我知道)的唯一方法。有人介意向我解释发生了什么事吗?这是完整的代码:
#include <stdio.h>
typedef void (*pFunc)();
int main()
{
char my_array[5];
char* a = my_array;
char* b = &my_array; // compiler error in c++, not in c
char* c = (char*)&my_array;
char** d = &my_array; // compiler error in c++, not in c
char** e = (char**)&my_array;
pFunc pFunc1 = (pFunc)&my_array; // works, but I don't really understand why
pFunc pFunc2 = (pFunc)my_array; // compiler error in c++, not in c
printf("char*:\n");
printf("0x%X\n", a);
printf("0x%X\n", b);
printf("0x%X\n", c);
printf("0x%X\n", d);
printf("0x%X\n", e);
printf("\n");
while(1);
return 1;
}
答案 0 :(得分:4)
C ++中的数组不是指针。当使用数组的名称初始化相应类型的指针时(例如当数组传递给适当指针类型的函数参数时),它将衰减为指针,但它本身不是指针
当您声明char my_array[5]
时,您正在创建一个包含5 char
个数组的数组;没有指针被创建,但是char[5]
存在并且可以被其他指针指向。
如果你执行char* a = my_array;
,my_array
会衰减为指针;创建了一个新的char*
,指向my_array
的第一个元素
char* b = &my_array;
失败,因为my_array
不是char
,因此&my_array
不是char*
。由于char** d = &my_array;
不是my_array
,因此char*
失败,因此&my_array
不是char**
。 &my_array
是char (*)[5]
(指向5 char
个数组的指针)。这些&#34;工作&#34;在C中,因为C只要求编译器发出警告,以便在不相关的指针类型之间进行隐式转换,但C ++根本不允许这些隐式转换;它们导致编译错误。您需要在C ++中进行显式转换,但即使这样,如果取消引用结果指针,行为也是未定义的。
最后,pFunc pFunc1 = (pFunc)&my_array;
&#34;工作&#34;类似地表示函数指针和对象指针的平台(大多数现代系统),但并不需要在所有平台上工作。同样,使用结果指针将调用未定义的行为
pFunc pFunc2 = (pFunc)my_array;
实际上也使用GCC编译,但无法在MSVC下编译。我实际上并不确定哪种编译器的行为是正确的,但无论哪种方式,结果都不太可能有用。
答案 1 :(得分:1)
定义数组时,会在内存中为其元素分配空间。整个空间(在您的情况下为5
个字节)分配给数组。因此,为数组元素以及数组本身分配空间。
应该注意,数组不是指针,反之亦然。 my_array
是一个数组而不是指针。在大多数情况下,数组转换为指向其第一个元素的指针,但并不意味着数组是指针。
数组my_array
的地址是char (*)[5]
类型,指向5 char
个数组的指针。它与类型char **
和pFunct
不兼容。分配不兼容的指针类型会导致错误。