zoukankan      html  css  js  c++  java
  • C++二级指针第二种内存模型(二维数组)

    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<<" ";
        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 
    ", 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 
    ", 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 
    ", 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 
    ", myArray[i]);
        }
    
        printf("第二种内存模型,排序之前
    ");
        printfArr23(myArray, 4);
        //printfArr23(myArray[10][30], 4);
    
        sortArr23(myArray, 4);    
    
        printf("第二种内存模型,排序之后
    ");
        printfArr23(myArray, 4);
        system("pause");
    }
  • 相关阅读:
    hdu6325 /// 上凸包
    hdu6315 /// 线段树区间更新
    hdu6311 /// 欧拉路径 无向图最小路径覆盖 输出正反路径
    Codeforces Round #535 F-MST Unification
    HDU4405 Aeroplane chess (概率DP,转移)
    ZOJ 3329 One Person Game(概率DP,求期望)
    poj3744 (概率DP+矩阵快速幂)
    “美登杯”上海市高校大学生程序设计 E. 小花梨的数组 (线段树)
    关于标记的一些事~~
    关于C(n,m) 的奇偶 ,与C(n,0),C(n,1),C(n,2)…C(n,n).当中有多少个奇数
  • 原文地址:https://www.cnblogs.com/CentForever/p/4640683.html
Copyright © 2011-2022 走看看