网站首页 > 基础教程 正文
C/C++中的数组名是个很奇怪的东西,它到底代表什么呢?
对于char array[n](n是一个常数),大概有这么几种语义:
<1> char* const(注意不是const char*) <2> char [n]
举例如下:
<1> char *p = array; //array表示char* const,p得到的是数组的首地址
size_t size = sizeof(char [n]); // size等于n
<2> char (*p)[n] = &array; // array表示char [n],
// p得到的仍然是数组的首地址
char (*q)[n] = array; // 编译错误
char (*r)[n] = (char (*)[n])array; // r得到的是array数组的首地址
<3> char (&p)[n] = array; // array表示 char [n]
<4> void foo(char a[n])
{
int size = sizeof(a); // size == 4(32位系统),
// 因为a实际上表示的是char*
};
foo(array); // array表示char* const
<5> void foo(char (&a)[n]);
{
int size = sizeof(a); // size == n
};
foo(array); // array表示char [n]
<6> void foo(char (*a)[n]);
{
int size = sizeof(*a); // size == n
};
foo(&array); // array表示 char [n]
<7> char *p;
array = p;
// 编译错误"error C2440,无法从char*转化为char [n]",因此array表示char [n]
<8> char other[n];
array = other; // 编译错误"error C2106, '='左操作数必须为L值",
// 因此array表示char [n]
(char (&)[n])array = other;
// 执行完后array的头4个元素表示的32位数与other代表的数组首地址相同,
// 在这里other被解释成char* const
(char (&)[n])array = (char [n])other;
// 执行完后array的头4个元素表示的32位数与other代表的数组首地址相同
(char (&)[n])array = (char (&)[n])other;
// 执行完后array数组与other数组的头四个元素相等
(char (*&)[n])array = (char (*)[n])other;
// (char (*&)[n])表示的是一个引用类型,
// 这个引用关联到一个指向char[n]数组的指针,
// 执行完后array的头4个元素表示的32位数与other代表的数组首地址相同
(__int64&)array = (__int64&)other;
// 执行完后array数组与other数组的头8个元素相等
<9> long i = 0;
(long &)array = i;
// 实际改变的不是array本身的值, 而是它代表的数组中的头4个元素(32位),因此array代表的是char [n]
<10> long i = 0;
(char (&)[n])i = array;
// 假设array数组首地址为0x0012feac, 则指令执行后i == 0x0012feac
<11> long i = 0;
(char (&)[n])i = (char (&)[n])array;
// 执行后i的值等于array头4个元素代表的32位数(32位系统)
<12> (char *&)array = "string";
// 执行后array头4个元素代表的32位数与 "string"常量字符串在内存中的地址相同
<13> (char (&)[n])array = (char (&)[n])"string";
// array数组的头4个元素依次为's','t','r','i'
当我们进行(char [n])array这样的强制转换时,效果与(char* const)array转换相当,都被解释成表示数组首地址的指针。但是两者还是有微妙区别的:sizeof(char [n])等于n,sizeof(char* const)等于4(32位系统),而且象(char [m])array这样的转换就不允许,其中m不等于n。如果我们用某种引用类型强制转换数组名时,编译系统会将转换结果(引用类型)自动关联到从数组首地址开始的内存区,而非数组名本身所在的内存区(它是否真的存在于内存中都是个未知数)。
当我们用这样强制转换过的数组名做赋值操作的左操作数时,改变的就是数组名代表的数组内存区了,而被改变的内存区的大小就要视引用类型而定,比如__int64&,那么大小就是8字节,其余类推。因为(char [n])与(char* const)效果基本相当,结果都被解释成指针,所以(char (&)[n])与(char* const &)也基本相当,结果就被解释成关联到指针的引用。当用(char (&)[n])array做赋值操作的右操作数时,实际上会从array数组首地址开始的内存区读sizeof(char* const)大小的数据,然后赋值给左操作数。这就可以解释为什么(char (&)[n])array = (char (&)[n])other执行后array与other的头4个元素相等了。
希望对大家有帮助~
学习C/C++编程知识,想要成为一个更加优秀的程序员,或者你学习C/C++的时候有难度,可以关注+私信小编【C/C++编程】笔者的C语言C++零基础编程学习圈,里面不仅有学习视频和文件资料,还有更多志同道合的朋友,欢迎转行也学习编程的伙伴,和大家一起交流成长会比自己琢磨更快哦!
猜你喜欢
- 2024-11-12 C语言之一维数组 c语言一维数组排序
- 2024-11-12 总结系列合集:C++中的动态数组 c+ 动态数组
- 2024-11-12 C语言结构体,如何定义结构体数组?linux C第62讲
- 2024-11-12 数组不可以直接赋值,为什么结构体中的数组却可以?
- 2024-11-12 C/C++编程笔记:C数组、字符串常量和指针!三分钟弄懂它
- 2024-11-12 数据结构入门:数组介绍 数据结构之数组
- 2024-11-12 再说,数组 数组+数组
- 2024-11-12 c++入门教程:c++中的动态数组 c++动态数组怎么用
- 2024-11-12 c++数组指导 c++数组的定义与使用
- 2024-11-12 C++基础概念:指针与数组,指针运算,指针与机器物理地址
- 最近发表
- 标签列表
-
- jsp (69)
- gitpush (78)
- gitreset (66)
- python字典 (67)
- dockercp (63)
- gitclone命令 (63)
- dockersave (62)
- linux命令大全 (65)
- pythonif (86)
- location.href (69)
- dockerexec (65)
- tail-f (79)
- queryselectorall (63)
- location.search (79)
- bootstrap教程 (74)
- deletesql (62)
- linuxgzip (68)
- 字符串连接 (73)
- html标签 (69)
- c++初始化列表 (64)
- mysqlinnodbmyisam区别 (63)
- arraylistadd (66)
- mysqldatesub函数 (63)
- window10java环境变量设置 (66)
- c++虚函数和纯虚函数的区别 (66)