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

    指针数组:首先它是一个数组,数组的元素都是指针。它是“储存指针的数组”的简称。int *p1[10];
    数组指针:首先它是一个指针,它指向一个数组。它是“指向数组的指针”的简称。   int (*p2)[10];

    这里需要明白一个符号之间的优先级问题,关键在于p1、p2先和谁结合。
    “[]”的优先级比“*”要高。p1 先与“[]”结合,构成一个数组的定义,数组名为 p1,int *修饰的是数组的内容,即数组的每个元素。那现在我们清楚,这是一个数组,其包含 10 个指向 int 类型数据的指针,即指针数组。
    至于 p2 就更好理解了,在这里“()”的优先级比“[]”高,“*”号和 p2 构成一个指针的定义,指针变量名为 p2,int 修饰的是数组的内容,即数组的每个元素。数组在这里并没有名字,是个匿名数组。那现在我们清楚 p2 是一个指针,它指向一个包含 10 个 int 类型数据的数组,即数组指针。

    我们可以借助下面的图加深理解:

    上述摘自:《C语言深度解剖》

    关于指针数组和数组指针的代码:

    #include <iostream>
    using namespace std;
    int main()
    {
    	int *p1[3];
    	int (*p2)[3];
    	int a[3] = {1,2,3};
    	int b[2][3] = {{1,2,3}, {4,5,6}};
    
    	p1[0] = &a[0];//int *
    	p1[1] = &a[1];//int *
    	p1[2] = a + 2;//int *
    	for (int i = 0; i < 3; i++)
    		cout << *p1[i] << " ";
    	//output:1 2 3
    
    	p2 = &a;	  //int (*)[3]
    	for (int i = 0; i < 3; i++)
    		cout << (*p2)[i] << " ";
    	//output:1 2 3
    
    	p2 = &b[1];   //int (*)[3]
    	for (int i = 0; i < 3; i++)
    		cout << (*p2)[i] << " ";
    	//output:4 5 6
    }

    明确两点

    1. int a[3] = {1, 2, 3};

    a是数组的首元素的首地址,具体地说是一个具有3个整型变量的数组的名字,而&a是整个数组的首地址,其值相同但意义不同。
    编译器根据我们提供的类型和数组大小,为我们分配了适当大小的存储区域,并且把这块存储区域叫做a。请注意 :&a,它的类型是“指向具有 3 个整型变量数组的指针“,简而言之&a是一个数组指针。

    2. &a+1

    式子&a+1表示的是指针加法运算,而不是普通的数值加法运算,之所以会这样是因为&a是一个指针而非普通数值(虽然它本质上也是一个整数)。假如此时&a=0xFFFF5700,那么&a+1是多少呢?答案是:取决于&a的类型 。
      a) 如果&a是一个指向char型的指针,那么&a+1 = 0xFFFF5701
      b) 如果&a是一个指向short型的指针,那么&a+1 = 0xFFFF5702
      c) 如果&a是一个指向int型的指针,那么&a+1 = 0xFFFF5704 (32位机器)
      d) 如果&a是一个指向某种结构体struct foo的指针,那么&a+1 = 0xFFFF5700+sizeof(struct foo)
      ……

    指针加1不是指针内容简单地加1,而是让指针指向下一个数据,这个数据的类型就是指针指向的类型,所以指针的加法究竟会让这个指针指向哪里,取决于这个指针指向的数据类型。
    因此,综上所述,当&a与整数1做加法时,实际上是指针的加法,加1的含义是:令指针a指向下一个数据 ,下一个数据是啥?当然是紧挨着的下一个具有3个整型变量的数组了(因为&a的类型是指向具有3个整型变量的数组的指针)。

    扩展阅读:林世霖 -- 一道试题引发的血案

  • 相关阅读:
    实例模拟struts核心流程
    不同语言下的日期格式化大全
    Android基础之响应Menu键弹出菜单Demo
    c++复习基础要点02 虚函数与模板 与static inline是否共存
    Android listView scroll 恢复滚动位置
    centos本地源搭建——iso
    easy_install和pip区别
    在前台运行Service
    mybatis处理集合、循环、数组和in查询等语句的使用
    java并发库 Lock 公平锁和非公平锁
  • 原文地址:https://www.cnblogs.com/li-chong/p/3266426.html
Copyright © 2011-2022 走看看