c++ - 关于 "Address-of operator"(&)和c、c++中数组的问题

标签 c++ c arrays pointers

我发现在用 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/

相关文章:

c++ - 我可以扩展一个参数包并用它定义一个参数列表吗?

c++ - 数组递归;无法获得正确的返回值

java - 如何启动一个带有可选命令行参数(即文件名)的 java eclipse 程序

c++ - 在递归 n-queen 程序中获取 C++ Segmentation Fault 错误

c++ - long * tempArray[10]; 是什么意思?做?

c++ - 表达式 : _CrtlsValidHeapPointer(pUserData) error

c++ - std::mem_fn 返回的函数对象是否需要 const 重载

c++ - 如何将 ffmpeg 视频帧转换为 YUV444?

c - vim 的高效非交互使用

c - 在 C 中添加更多局部变量时出现 EXC_BAD_ADDRESS