我发现在用 c 编译时与用 c++ 编译时有一个我不完全理解的区别...假设我声明了一个大小为 5 的 char 数组:
char my_array[5];
根据我的理解,“my_array”实际上是一个字符指针,它允许我这样做:
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
我不明白其中的区别,为什么 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;
}
最佳答案
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** d = &my_array;
失败,因为 my_array
不是 char*
,因此 &my_array
不是t 一个 char**
。 &my_array
是一个 char (*)[5]
(指向 5 个 char
的数组的指针)。这些在 C 中“起作用”是因为 C 只要求编译器对无关指针类型之间的隐式转换发出警告,但 C++ 根本不允许这些隐式转换;它们会导致编译错误。您需要在 C++ 中进行显式转换,但即使这样,如果您取消引用结果指针,行为也是未定义的。
最后,pFunc pFunc1 = (pFunc)&my_array;
在类似地表示函数指针和对象指针的平台(大多数现代系统)上“工作”,但它不需要在所有平台上工作.同样,使用结果指针将调用未定义的行为。
pFunc pFunc2 = (pFunc)my_array;
实际上也可以使用 GCC 进行编译,但无法在 MSVC 下进行编译。我实际上不确定哪个编译器的行为是正确的,但无论哪种方式,结果都不太可能有任何用处。
关于c++ - 关于 "Address-of operator"(&)和c、c++中数组的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34536797/