MyU*_*358 2 c c++ arrays pointers
我发现在 c 中编译时与在 c++ 中编译时存在差异,但我不完全理解......假设我声明了一个大小为 5 的 char 数组:
char my_array[5];
Run Code Online (Sandbox Code Playgroud)
根据我的理解,“my_array”实际上是一个 char 指针,它允许我这样做:
char* a = my_array;
Run Code Online (Sandbox Code Playgroud)
现在,我明白,当我声明数组时,我只分配了 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
Run Code Online (Sandbox Code Playgroud)
我不明白其中的区别,为什么 c 会允许这样做?不过,假设我想将 char[5] 转换为 char*,而不使用 a 的方法,我发现我也可以这样做:
char* c = (char*)&my_array; // works both in c and c++
Run Code Online (Sandbox Code Playgroud)
那个我实在是看不懂。我没有确定“&my_array”不存在吗?更令人担忧的是,这两行返回相同的精确值:
// a and c have the same value (both in c and c++)
char* a = my_array;
char* c = (char*)&my_array;
Run Code Online (Sandbox Code Playgroud)
接下来,假设我想在运行时执行这 5 个字节,因此我声明一个新类型:
// pFunc is a pointer to function returning void
typedef void (*pFunc)();
Run Code Online (Sandbox Code Playgroud)
然后我尝试声明一个指向将执行我的字节数组的函数的指针:
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
Run Code Online (Sandbox Code Playgroud)
突然之间,不仅 &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;
}
Run Code Online (Sandbox Code Playgroud)
C++ 中的数组不是指针。当使用数组的名称初始化适当类型的指针时(例如,当将数组传递给适当指针类型的函数参数时),它将衰减为指针,但它本身不是指针。
当你声明 时char my_array[5],你正在创建一个 5 的数组char;没有创建指针,但 achar[5]存在并且可以被其他指针指向。
如果这样做char* a = my_array;,my_array将衰减为指针;创建一个新的char*指向 的第一个元素my_array。
char* b = &my_array;失败,因为my_array不是 a char,因此&my_array也不是 a char*。 char** d = &my_array;失败,因为my_array不是 a char*,因此&my_array也不是 a char**。 &my_array是一个char (*)[5](指向 5 数组的指针char)。这些在 C 中“起作用”,因为 C 仅要求编译器对不相关的指针类型之间的隐式转换发出警告,但 C++ 根本不允许这些隐式转换;它们会导致编译错误。您需要在 C++ 中进行显式转换,但即使如此,如果您取消引用结果指针,行为也是未定义的。
最后,pFunc pFunc1 = (pFunc)&my_array;在类似地表示函数指针和对象指针的平台(大多数现代系统)上“工作”,但并不需要在所有平台上工作。同样,使用结果指针将调用未定义的行为。
pFunc pFunc2 = (pFunc)my_array;实际上使用 GCC 也可以编译,但在 MSVC 下编译失败。我实际上不确定哪个编译器的行为是正确的,但无论哪种方式,结果都不太可能有任何有用的东西。