數組名取地址以及數組名作爲sizeof操作符的操作數

數組名取地址十分好玩,在這裏記錄一下,如果大家有不同見解,歡迎留言探討:


    在大多數情況下,數組名都會默認轉換爲指向數組的第一個元素的指針。這一點相信大家都知道。比如下邊的例子:

        

  int array[3] = {1,2,3};
  
  cout << *array << endl;
  
  cout << array[0] << endl;

        上邊的兩個輸出的值是相同的,這個時候array作爲數組名默認轉換爲指向數組的第一個元素的指針。對數組名稱進行解引用得到的是數組的第一個元素的值。因此兩個輸出語句的值時相同的。


        


    當數組名作爲取地址操作符的操作數的時候情況比較有意思,這個時候數組名不是默認轉換爲數組的第一個元素的指針。下邊來用例子稍微驗證一下。


        (1)對數組名作爲取地址操作符的操作數得到的值和數組名默認轉換成指向第一個元素的指針的值相同。

    

	int array[3] = {1, 2, 3};
	int *ptr = &array;
	cout << "array = " << array << endl;
	cout << "ptr = " << ptr << endl;

        這個時候我們編譯的話,編譯器一般都會報錯的,如下所示。這個時候我們看一下報錯的信息就可以知道對數組名取地址得到的結果其實是一個: int(*)[3] ,表示的是這個指針指向的是整個數組對象,也就是說這個指針指向的是:數組起始地址開始的,以 數組長度和sizeof(int)乘積爲寬度的一個數據對象(我是這麼理解的,大家如果有不同的見解可以在下邊留言一起討論)。sizeof(int)是針對例子程序來分析的,不同的數據類型需要我們更換sizeof的操作數。


      (2)對於例子1種的報錯信息,我們更換ptr的聲明方式來修正一下上邊的例子:

	int array[3] = {1, 2, 3};
	int (*ptr)[3]  = &array;
	cout << "array = " << array << endl;
	cout << "ptr =   " << ptr << endl;
	cout << "ptr+1 = " << (ptr + 1) << endl;

                運行結果如下:



            對於(1)種的報錯信息,我們還可以進行下邊的修正:

    

	int array[3] = {1, 2, 3};
	int (*ptr)[3]  = &array;
	int *ptr2 = (int*)&array;
	cout << "array = " << array << endl;
	cout << "ptr =   " << ptr << endl;
	cout << "ptr2  = " << ptr2 << endl;

          輸出結果如下:

    


    這兩種修正方式得到的指針的值時相同的,但是這兩個指針的意義卻又不盡相同,參照下邊的代碼:

	int array[3] = {1, 2, 3};
	int (*ptr)[3]  = &array;
	int *ptr2 = (int*)&array;
	cout << "array = " << array << endl;
	cout << "ptr =   " << ptr << endl;
	cout << "ptr2  = " << ptr2 << endl;
	cout << "ptr+1= " << (ptr + 1) << endl;
	cout << "ptr2+1=" << (ptr2 + 1) << endl;

            輸出的結果如下:

    

        可以看到,雖然array和ptr的值是相同的,但是使用指針加一得到的結果卻是完全不同的。對於未經強制轉換得到指針的值加一得到的是以整個數組爲基本單元,向後移動數組大小的空間得到的指針值。對於強制轉換的指針加一相當於偏移一個整形指針的長度。



    指針取地址之後的指針值是和普通的指針是不一樣的,這個時候的加上1之後的偏移量是一個數組的空間大小。



另外一個數組比較特殊的就是sizeof操作符。sizeof操作符的操作數是數組名的時候,得到的是整個數組的大小,即: int array[10].   sizeof(array)/sizeof(int) = 10;

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章