分享

C/C++编程笔记:C/C++中数组名的含义,不同数组名有不同的含义

 新用户0175WbuX 2022-01-31

  C/C++中的数组名是个很奇怪的东西,它到底代表什么呢?

  C/C++编程笔记: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]

  C/C++编程笔记:C/C++中数组名的含义,不同数组名有不同的含义

  <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位系统)

  C/C++编程笔记:C/C++中数组名的含义,不同数组名有不同的含义

  <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。如果我们用某种引用类型强制转换数组名时,编译系统会将转换结果(引用类型)自动关联到从数组首地址开始的内存区,而非数组名本身所在的内存区(它是否真的存在于内存中都是个未知数)。

  C/C++编程笔记:C/C++中数组名的含义,不同数组名有不同的含义

  当我们用这样强制转换过的数组名做赋值操作的左操作数时,改变的就是数组名代表的数组内存区了,而被改变的内存区的大小就要视引用类型而定,比如__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个元素相等了。

  希望对大家有帮助~

    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多