zoukankan      html  css  js  c++  java
  • 指针与数组

    1.通过数组和下标实现的表达式可以等价的通过指针和偏移量实现。

    例如:

    int a[]=  {1,4,66,8};

    *p = a;

    p = &a[0];//和上面一句等价

    *(p+1) 和a[1]和*(a+1)是等价的

    a+1和&啊&a[1]也是等价的。

    2.数组作为函数参数在传参时会自动退化为普通指针

    int Srlen(char string[]);

    在此函数中若调用系统的字符串长度函数sizeof会发现算不出正确的字符串长度

    int Size(char string[])
    {
        return sizeof(string);
    }


    int _tmain(int argc, _TCHAR* argv[])
    {
        char pStr[] = {'a','b'};

         cout<<sizeof(pStr)<<endl;
         cout<<Size(pStr)<<endl;

         return 0;

    }

    得出结果为2,4

    数组是一个完备的变量类型,有名字、大小、地址,只不过名字和它的首地址一样罢了,所以用sizeof对数组名

    进行计算时算出的是实际数组的大小,而不是指针大小。

    3.c/c++默认的是值传递,这个是临时想起来的,也放到这篇里了

    double *p = NULL;
    fun(p);
    if (p == NULL)
    {
        cout<<"p not changed"<<endl;
    }
    else
    {
        cout<<"p changed"<<endl;
    }

    结果为:p not hanged

    如果想要改变指针的值还是要址传递参数,这里很容里犯错。下面是正确的做法

    double* fun(double **p)
    {
        *p = new double;
        return *p;
    }


    int _tmain(int argc, _TCHAR* argv[])
    {
        double *p = NULL;
        fun(&p);
        if (p == NULL)
        {
            cout<<"p not changed"<<endl;
        }
        else
        {
            cout<<"p changed"<<endl;
        }
       
        getchar();
        return 0;
    }

    4.二维数组的等价访问方式

    数组名是一个const指针。

    再次强调

    数组是一个完备的变量类型,有名字、大小、地址,只不过名字和它的首地址一样罢了,所以用sizeof对数组名

    进行计算时算出的是实际数组的大小,而不是指针大小。也正是因为如此,指向数组的指针指向指针有些不一样

    最明显的不同就是表现在指针进步的时候我们知道指针在++进行运算的时候,跨越的实际地址取决于指针指向的

    数据类型。例如在32位字长机器中指向int型数据跨越的实际地址是4,指向指针类型也是4.指向数组类型的时候,

    跨越的实际地址就是数组的长度了。

    int a[3][3] = {1,2,3,4,5,6,7,8,9};

    下面三种初始化或者复制方式都会编译出错:

    int **p = a;
    int *p = NULL;
    p = &a;
    下面两个是正确的:

    p = &a[0][0];

    int (*q)[3] = a;  //指向含有三个元素的数组的指针,下面会介绍

    再看看用这两个正确的方式如何访问数组元素

    遍历:

    //用p来遍历二维数组
    for (int i = 0;i < 12;i++)
    {
        cout<<*(p++)<<endl;
    }

    //用q来遍历二维数组
    for (int i = 0;i < 4;i++)
    {
        for (int j = 0;j < 3;j++)
        {
            cout<<q[i][j]<<endl;
        }
    }


    看看下面输出的是什么:

    for (int i = 0;i < 4;i++)
    {
        cout<<q[i]<<endl;//这里i++或者q++一次就是移动了三个整形元素数组的空间
    }

    是a[0][0]、a[1][0]、a[2][0]、a[3][0]的地址

    下面就很清楚了:

    for (int i = 0;i < 4;i++)
    {
    cout<<*q[i]<<endl;
    }

    输出的是a[0][0]、a[1][0]、a[2][0]、a[3][0]的值

    首地址a也可以像q一样访问数组元素:

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

    for (int i = 0;i < 4;i++)//a++有一样的效果
    {
        cout<<a[i]<<endl;
        cout<<*a[i]<<endl;
    }

    输出:

    4G4N_Y)6K}__8T{(7@I6G2Q

    看看下面代码的输出

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

    for (int i = 0;i < 4;i++)
    {
        for (int j = 0;j < 3;j++)
        {//输出每一个元素的地址和值
            cout<<&a[i][j]<<" "<<a[i][j]<<endl;;
        }
    }

    for (int i = 0;i < 4;i++)
    {
        for (int j = 0;j < 3;j++)
        {
            cout<<((*a+i)+j)<<endl;
            cout<<(*a+i+j)<<endl;      //这就相当于用*a取得首地址,后面再加就相当于是在处理一维数组指针,跟前面的p一样
            //cout<<*((*a+i)+j)<<endl;
        }
    }

    输出:

    D%9{O6{Z8TG`S_P419B))XS

    for (int i = 0;i < 12;i++)
    {
        //从头到尾遍历每个元素的地址和值
        cout<<(*a+i)<<"  "<<*(*a+i)<<endl;
    }

    输出:

    GSB(UVV0A)RG3048RWH$~C7

    5.如何new一个二维数组(动态创建二维数组)

    int row = 0;
    int column = 0;
    cin>>row>>column;
    int **p = new int*[row];
    int k = 1;

    for (int i = 0;i < row;i++)
    {
        p[i] = new int[column];
        for (int j = 0;j < column;j++)
        {
            p[i][j] = k++;
        }
    }

    int *q = &p[0][0];
    for (int i = 0;i < row*column;i++)
    {
        //因为此处p这个二维数组是new了两次创建的,里面的元素不是像a[4][7]一样在内存中
        //顺序排列的,所以用这种方法无法正常打印出二维数组的值
        cout<<(q+i)<<endl;
        cout<<*(q+i)<<endl;
    }

    //下面是一种遍历动态创建的二维数组的正确方法
    for (int i = 0; i < row;i++)
    {
        for (int j = 0; j < column;j++)
        {
            cout<<p[i][j]<<endl;
        }
    }

    上面代码运行结果如下:

    image

    6.指针数组与数组指针

    //()的优先级高,首先说明q是一个指针,指向一个整型的一维数组,这个数组的长度为4。
    int (*q)[4] = a;//指向含有4个元素的数组的指针,q++每次移动一行

    //[]的优先级高,先与p结合成一个数组,再由int*说明这是一个整型指针数组,它有3个整数指针类型的数组元
    int *p[3] = {&a[0][2],&a[1][0],&a[2][0]};//指针数组,顾名思义就是存放指针的数组,就像定义普通数组一样

    生命在于折腾,生活就是如此的丰富多彩
  • 相关阅读:
    C#使用 System.Net.Mail发送邮件功能
    移动H5前端性能优化指南
    chrome主页被篡改为hao123 win10系统
    jqGrid TreeGrid 加载数据 排序 扩展
    Dapper 链式查询 扩展
    T4 代码生成 Demo (抽奖程序)
    反射实现 Data To Model
    highcharts .net导出服务 和 两种导出方式
    jQuery 自定义插件 (分页控件)
    ajax 多级联动 下拉框 Demo
  • 原文地址:https://www.cnblogs.com/Mr-Zhong/p/4138259.html
Copyright © 2011-2022 走看看