歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

C++二級指針第二種內存模型(二維數組)

二維數組

  二維數組本質上是以數組作為數組元素的數組,即“數組的數組”。

定義

  類型說明符 數組名[常量表達式][常量表達式]

  例如:

  float a[3][4],b[5][10];

二維數組元素地址

#include <iostream>

using namespace std;

int main()
{
    cout << "Hello world!" << endl;
    int a[3][4]={
        {1,2,3,4},
        {5,6,7,8},
        {9,10,11,12}
    };

    int * p ;
        // p=a ;  錯誤
        p =a[0]; // ok
    for(int i=0;i<12;i++)
        cout<<*(p+i)<<"--------"<<p+i<<endl;

    cout<<a<<endl;  // a 與a[0]地址是一樣的.
    cout<<a[0]<<endl;
    return 0;
}

  可以看出二維數組的內存地址是連續的。

  因此,在棧區是占有一塊連續的內存。

#include <iostream>

using namespace std;

int main()
{
  int a[3][4]={
        {1,2,3,4},
        {5,6,7,8},
        {9,10,11,12}
    };

    int * p ;
    // p=a ;  錯誤
    p =a[0]; // ok
    for(int i=0;i<12;i++)
    cout<<*(p+i)<<"--------"<<p+i<<endl;

    cout<<"-----------------------"<<endl;
    cout<<"a    = "<<a<<endl;      // 發現 a與a[0]地址是一樣的 : 0012FF50
    cout<<"a[0]  = "<<a[0]<<endl;
    cout<<"*a    = "<<*a<<endl;


    // 下面3條原以為是輸出的元素的數值,結果 *a還個地址,且與a一樣的值
    //  可見二維數組的名 是個 二級指針, a 是地址的地址
    cout<<"-----------------------"<<endl;
    cout<<"(*a)    =  "<<(*a)<<endl;          // 對應元素1的地址  0012FF50
    cout<<"(*(a+1)) =  "<<(*(a+1))<<endl;      // 對應元素5的地址  0012FF60
    cout<<"(*(a+2)) =  "<<(*(a+2))<<endl;      // 對應元素9的地址  0012FF70

    cout<<"-----------------------"<<endl;
    cout<<"*(*a)      = "<<*(*a)<<endl;          //1
    cout<<"*(*(a+1))  = "<<*(*(a+1))<<endl;      //5
    cout<<"*(*(a+2))  = "<<*(*(a+2))<<endl;      //9


    cout<<"-----------------------"<<endl;
    cout<<"a[0]    =  "<<a[0]<<endl;    // 對應元素1的地址  0012FF50
    cout<<"a[1]    =  "<<a[1]<<endl;    // 對應元素5的地址  0012FF60
    cout<<"a[2]    =  "<<a[2]<<endl;    // 對應元素7的地址  0012FF70
    return 0;
}

  /***********************************************************/ 

 

片段:
int a[3][3]={{1,2,3},{4,5,6},{7,8,9}};
    int *p;
    p=a;  //? a是這個二維數組的首地址,但為什麼p=a就不行?
    cout<<a<<"\n";
    cout<<p<<endl;

直接“cout<<a”可以看到地址 就是a[0][0]
可是為什麼p=a就不行呢?a不是二維數組首地址嗎?為什麼非要用p=a[0]?
請教!

Ans  ----------->

 數據類型不同
p是指向int的指針
a可以看成指向int [3]的指針
int 和 int [3]不是同樣的類型,
前者是簡單數據類型,後者是由簡單數據類型構成的數組類型.
正因為這兩種數據的類型不同,所以指向它們的指針的類型也不同.
指針運算是按照指針的類型進行的,
所以p++只使p移動一個整數所占的字節長度,
a++卻移動了三個整數所占的字節長度,
由指針運算就可以看出這兩個指針不是同類型的.

不過指針間的強制轉換一般都還可行,
因而可以如下:
p=(int*)a;

雖然 a 和 a[0] 的類型不同,但它們的值是一樣的.

但值一樣卻未必是同樣的數據類型!

Ans  ----------->

在除了sizeof、&和字符串常量之外的表達式中,array type會被自動轉換為pointer type。

對於p=a;這一句,a的類型是array type,就是int[3][3],a在賦予p之前,其類型先被自動轉換為pointer type,就是int(*)[3],轉換的結果是指向數組的指針,而p的類型是int*,是指向整數的指針,兩者類型不相容,不能直接賦值。

a[0]的類型也是array type,就是int[3],

同樣地,在表達式p=a[0]中a[0]也會先被自動轉換為pointer type,

就是int*,跟p的類型相容,因此可以p=a[0]。

Ans  ----------->

解釋如下:
例如
int a[2][4]是一個二維數組,包含8個元素
這個數組表示為什麼呢:
表示為a數組有兩個元素(可以想象成一個結構,由4個int組成)
a就是這個數組的指針,指到a這個二維數組的第一個元素,即a[0](4個int組成的)
當你賦值的時候,編譯器認為a是一個4元素的結構,而p是一個int指針,類型不匹配,因此錯誤.
而a[0]則是a[0][0]的地址,a[0]的類型是int *,與p匹配,因此可以.

  /***********************************************************/ 

舉例:

#include "stdio.h"
#include "stdlib.h"
#include "string.h"
void main()
{
    int i = 0, j = 0;
    char buf[30];
    char myArray[10][30] =  {"ccccc", "aaaa", "bbbb","11111"}; 
    //打印第二種內存模型
    for (i=0; i<4; i++)
    {
        printf("%s \n", myArray[i]);
    }
    //排序
    for (i=0; i<4; i++)
    {
        for (j=i+1; j<4; j++)
        {
            if (strcmp(myArray[i], myArray[j]) > 0)
            {
                strcpy(buf, myArray[i]);
                strcpy(myArray[i],myArray[j]);
                strcpy(myArray[j], buf);
            }
        }
    }
    //打印第二種內存模型
    for (i=0; i<4; i++)
    {
        printf("%s \n", myArray[i]);
    }
    system("pause");
}

#include "stdio.h"
#include "stdlib.h"
#include "string.h"

//int array[10]===>int *array===>
//    int    printfArr22(char array[10], int iNum);
int    printfArr23(char myArray[10][30], int iNum)
{
    int i = 0;
    for (i=0; i<iNum; i++)
    {
        printf("%s \n", myArray[i]);
    }
    return 0;
}

//    int    printfArr22(char array[10], int iNum);
int    sortArr23(char myArray[10][30], int iNum)
{
    int i = 0, j = 0;
    char buf[30]; //buf數組名代表數組首元素的地址
    //排序
    for (i=0; i<4; i++)
    {
        for (j=i+1; j<4; j++)
        {
            if (strcmp(myArray[i], myArray[j]) > 0)
            {
                strcpy(buf, myArray[i]);
                strcpy(myArray[i],myArray[j]);
                strcpy(myArray[j], buf);
            }
        }
    }
}

void main()
{
    int i = 0;
    char myArray[10][30] =  {"ccccc", "aaaa", "bbbb","11111"}; //myArray數組名代表什麼?拋磚

    //打印第二種內存模型
    for (i=0; i<4; i++)
    {
        printf("%s \n", myArray[i]);
    }

    printf("第二種內存模型,排序之前\n");
    printfArr23(myArray, 4);
    //printfArr23(myArray[10][30], 4);

    sortArr23(myArray, 4);   

    printf("第二種內存模型,排序之後\n");
    printfArr23(myArray, 4);
    system("pause");
}

Copyright © Linux教程網 All Rights Reserved