为什么char[]和char*作为typedef不同,但有时.不
Why are char[] and char* as typedefs different, but sometimes... not?
当我关注这个关于char[]
和char*
差异的问题时,出现了以下观察结果。
#include <iostream>
typedef char ar[];
typedef char* pr;
void f2(ar x, pr y)
{
std::cout << std::is_same<decltype(x), decltype(y)>::value << 'n';
std::cout << std::is_same<ar, pr>::value << 'n';
}
int main()
{
char data[] = "data";
char *ptr = data;
f2(data,ptr);
return 0;
}
输出(在Apple LLVM 4.2版(clang-425.0.28)上)
1
0
为什么这些报告为不同的类型,而不是不同的decltype()
?我的怀疑是,由于它们的typedef
声明,它们实际上是不同的类型,但为什么变量被报告为相同的类型?
在C++中,与在C中一样,被声明为数组类型的参数(在编译时)被调整为指针类型,特别是指向数组元素类型的指针。
无论是直接指定数组类型还是通过typedef指定数组类型,都会发生这种情况(请记住,typedef不会创建新类型,只是现有类型的别名)。
所以这个:
typedef char ar[];
typedef char* pr;
void f2(ar x, pr y)
{
// ...
}
真正的意思是:
void f2(char* x, char* y)
{
// ...
}
同样由C和C++共享的另一条规则是,在大多数但不是所有上下文中,数组类型的表达式都会隐式地将转换为指向数组对象第一个元素的指针。这意味着,如果您定义一个数组对象:
char arr[10];
可以将该对象的名称用作函数的参数,该函数使用char*
参数(将丢失边界信息)。
在C中,这种隐式转换没有发生的情况是:
- 当数组表达式是
sizeof
的操作数时(sizeof arr
产生数组的大小,而不是指针的大小) - 当数组表达式是一元
&
的操作数时(&arr
是指向数组的指针,而不是指向指针的指针);以及 - 当数组表达式是用于初始化数组类型的对象的字符串文字时(
char s[] = "hello";
将s
初始化为数组,而不是指针)
这些情况(或C++中出现的其他情况)都没有出现在您的程序中,所以您的调用:
f2(data,ptr);
将类型为CCD_ 12到CCD_。
在f2
内部,参数对象x
和y
都属于char*
类型,因此std::is_same<decltype(x), decltype(y)>::value
为true。
但CCD_ 19和CCD_。ar
是不完全数组类型char[]
,而pr
是指针类型char*
。
它解释了程序的输出。之所以会出现这种奇怪的情况,是因为您使用数组类型ar
定义的参数x
实际上是char*
类型,与pr
类型相同。
C族是按值传递的,数组的C值是指向其第一个元素的指针。当你把一个声明为数组的项传递给一个函数时,真正传递的是那个指针,而C把原型当作你这样声明的。
我修改了代码,这样我们就可以看到调用f2是如何改变类型的。在调用之前,变量是不同类型的。通话后,他们变成了相同的
typedef char ar[];
typedef char* pr;
void f2(ar x, pr y)
{
cout << is_same<decltype(x), decltype(y)>::value << 'n'; //same type
}
int main()
{
ar data = "data";
pr ptr = data;
cout << is_same<decltype(data), decltype(ptr)>::value << 'n'; // different
f2(data,ptr);
return 0;
}
输出为00正如@jthill、@Dyp和@keith Thompson所说,这是因为指针数组的衰减。
- 在 Arduino 上使用 sscanf 会导致与 const char * 不匹配,并且返回值始终相同,尽管输入值不同
- 为什么strlen(s)与s的大小不同,为什么cout-char显示的是字符而不是数字
- 为什么这两段使用 constexpr、__PRETTY_FUNCTION__ 和 char * 的代码有不同的结果?
- 在变量名后声明带有 () 的非内部类型与不使用变量名的行为不同。即 std::map<int,char>x(); - 这是怎么回事?
- 通过 char* 缓冲区读取 int 的行为是不同的,无论是正数还是负数
- 为什么类型 char 返回不同的值?
- *char数组到字符串(两次运行代码和两个不同的结果)
- 如何将多个不同的字符串分配给 char* 数组
- 返回类型 char* 的成员函数返回在 while 循环后包含不同字符串的地址
- 数据结构对齐:为什么Char和STD :: String的数组不同
- QString 到 const char* 的不同结果
- 创建char阵列时,其长度与所需的长度不同
- "WORD":"char [20]"与"无符号短"的间接级别不同
- C++Visual Studio 2010如何在不同的函数中使用char类型变量
- 将SWIG应用于C++时,f1(const char*str)与f1(char*str)是否不同
- 通过指针传递char并获得不同的结果
- 转换char*时的值不同
- 需要接受教育:声明"void encrypt(char*, int)"具有不同的异常说明符"
- 为什么 char* 和 int* 的行为不同
- 为什么从int转换到char*与从std::string转换到char*不同?