• 数组与指针


    1. 数组与指针

    1.1  一维数组与指针

    例子:

    int a[] = { 1,2,3,4,5,6,7,8,9 ,0 };
    for (int *p = a; p < a + 10; p++)
    {
       std::cout << p << ',' << *p << std::endl;
    }

    指针格式:int a[10] 退化为指针是指向一个元素的指针,故int *p = a;

    访问数组的方式:p[i], *(p + i);

    1.1  二维数组与指针

    例子1:

    char *s[] = { "cacul","paint","notepad" };
    for (char**p = s; p < s + 3; p++)
    {
        std::cout << *p << std::endl;
    }

    上述内存模型可解释如下:

    数组s

    常量区

    地址A

    地址A

    cacul

    地址B

    地址B

    paint

    地址C

    地址C

    notepad

    数组s中实际存的是每个字符串的地址,所以可以使用二级指针去访问。实际解释如下:

    1. s中每个元素是一个地址,为char *类型,该地址指向一个字符数组。
    2. char* s[]实际也是一个指针数组,故只需再加一级指针就可以访问对应元素了。

    例子2:

    char *s2[3][10] = { "cacul","paint","notepad" };
    for (char**p = s2; p < s2 + 3; p++)
    {
        std::cout << *p << std::endl;
    }

    这个例子将无法编译通过,报错如下:

    a value of type "char *(*)[10]" cannot be used to initialize an entity of type "char **"

    说明二级指针和二维数组的指针的类型不同。

    结论: 地址相同不等价于类型相同,这里需要一个数组类型的指针

    例子3:

        char s2[3][10] = { "cacul","paint","notepad" };
        printf("%p,%d,%d
    %p,%d,%d
    %p,%d
    ", s2,  sizeof(s2),  sizeof(*(&s2)),
                                              &s2, sizeof(&s2), sizeof(*(*s2)),
                                              *s2, sizeof(*s2));

    运行结果:

    004AFB84,30,30

    004AFB84,4,1

    004AFB84,10

    结论:地址一样,但类型不一样,&s2整个数组的首地址,s2第一行的首地址,*s2第一个字符的地址。

    二维数组的遍历

    例子3:

        int b[3][4] = { 1,2,3,4,5,6,7,8,9,10,11,12 };
        //二维数组的遍历,因为在内存中是线性存储的
        for (int *p = &b[0][0]; p < &b[0][0] + 12; p++)
        {
            std::cout << *p << std::endl;
        }

    扩展:

    指针的运算

    int *p = &b[0][0];

    *(p+4); //等于5,实际移动的长度是4*sinzof(type)

    数组作为会退化为指针,即实际穿首地址。

    例子:

    int getSize(int a[3][4])
    {
        printf("%d", sizeof(a));
    
    }
    int main()
    
    {
        int b[3][4] = { 1,2,3,4,5,6,7,8,9,10,11,12 };
        getSize(b);
        system("pause");
        return 0;
    }

    运行结果:4

    1. 一维数组a[n]做参数会退化成指向第一个元素的指针
    2. 二维数组a[m][n]做参数也会退化成指向第一个元素的指针,而第一个元素是一个长度为n的数组,故是一个数组指针 (*p)[n];

    例子:

    int getMax(int (*a)[4])
    {
        int tmp = *(*(a + 0) + 0);
        for (int i = 0; i < 3; i++)
        {
            for (int j = 0; j < 4; j++)
            {
                if (a[i][j] > tmp)
                {
                    tmp = a[i][j];
                    //tmp = *(*(a + i) + j);
                }
            }
        }
        return tmp;
    }

    调用:

    std::cout << getMax(b) << std::endl;

    工具:

    API介绍:

    HWND *win = FindWindowA("ClassName", "WindowName");//寻找桌面窗口

    SetWindowPos(win,坐标,大小)用于设置窗口坐标和大小。

    1.2 三维数组

    例子:

        int c[3][4][5] = { 0 };
        for (int *p = &c[0][0][0], i = 0; p < &c[0][0][0] + 60; p++, i++)
        {
            *p = i;
        }
        int(*d)[4][5] = c;
        for (int i = 0; i < 3; i++)
        {
            for (int j = 0; j < 4; j++)
            {
                for (int k = 0; k < 5; k++)
                {
                    //std::cout << c[i][j][k] << "	";//这三种都可以
                    //std::cout << d[i][j][k] << "	";
                    std::cout << *(*(*(d+i)+j)+k) << "	";
                }
                std::cout << std::endl;
            }
            std::cout << std::endl << std::endl;
        }

    由二维数组一样可以扩展到三维数组,所需指针即为指向一个二维数组的数组指针。

    1.3 总结

    N级指针不可用于数组。(会报类型不同的错误)

    定义               指针                  访问

    int a[10];       int *p = a;           p[i]; *p;

    int b[3][4];     int (*b)[4] = b;     b[i][j]; *(*(b + i) + j);

    int c[3][4][5];  int(*d)[4][5] = c;   d[i][j][k]; *(*(*(d+i)+j)+k);

    GCC和VCC编译器的区别:

    GCC编译:

    int num = 100;

    int a[num];

    上述代码可以编译通过。

    VCC编译:

    int num = 100;

    int a[num];

    不能编译通过,必须为常量,即int a[100]。

    这种定义的变量都在栈里面,当定义int a[1024*1024]时会发生栈溢出。

  • 相关阅读:
    我是菜鸟,开始学习计划
    我是菜鸟,学习计划4月19日笔录
    用HttpSessionListener与HttpSessionBindingListener实现在线人数统计
    mac系统InetAddress.getLocalHost().getHostAddress() 很慢
    获取n位数m进制的随机数 js
    cordova开发环境搭建
    遇到网页中无法选择的文本时或需要登录才可复制时可用
    今天摸的鱼就是以后加的班
    国际化vuei18n 向语言包中传入参数
    vue3 技术浏览 收藏
  • 原文地址:https://www.cnblogs.com/UFO-blogs/p/9708374.html
Copyright © 2020-2023  润新知