zoukankan      html  css  js  c++  java
  • 二维数组名和二级指针

    1. 指针

    1.1 一个指针包含两方面:a) 地址值;b) 所指向的数据类型。

    1.2 解引用操作符(dereference operator)会根据指针当前的地址值,以及所指向的数据类型,访问一块连续的内存空间(大小由指针所指向的数据类型决定),将这块空间的内容转换成相应的数据类型,并返回左值。

    有时候,两个指针的值相同,但数据类型不同,解引用取到的值也是不同的,例如,

    1 char str[] ={0, 1, 2, 3};       /* 以字符的ASCII码初始化 */  
    2   
    3 char * pc = &str[0];        /* pc指向str[0],即0 */  
    4   
    5 int * pi = (int *) pc;      /* 指针的“值”是个地址,32位。 */  

    此时,pc和pi同时指向str[0],但*pc的值为0(即,ASCII码值为0的字符);而*pi的值为50462976。或许把它写成十六进制会更容易理解:0x03020100(4个字节分别为3,2,1,0)。我想你已经明白了,指针pi指向的类型为int,因此在解引用时,需要访问4个字节的连续空间,并将其转换为int返回。

    2. 数组

    2.1 数组名和指针

    通常我们认为数组名是一个指针常量(例如,int a[10]; 那么a是一个int * const),这种理解是不全面的,正确的理解如下:

    作为右值(例如,赋值语句右边)时数组名可视为指针常量(系统自动转换);作为左值,例如取地址,sizeof,则不能视为指针。

    sizeof(一个数组)返回的是数组大小*每个元素占字节数;而sizeof(一个指针)返回4。

    2.2 二维数组

    实际上,不管是一维还是多维数组,都是内存中一块线性连续空间,因此在内存级别上,其实都只是一维。

    int a[3][4] = {0,1,2,3,4,5,6,7,8,9,10,11};  
      
    int ** p;  
      
    p = (int**)a;       /* 不做强制类型转换会报错 */  

    说明:

    1)p是一个二级指针,它首先是一个指针,指向一个int*;

    2)a是二维数组名,它首先是一个指针,指向一个含有4个元素的int数组;

    由此可见,a和p的类型并不相同,如果想将a赋值给p,需要强制类型转换。

    3. 为什么不能将二维数组名传递给二级指针?

    假如我们将a赋值给p,p = (int**)a; 既然p是二级指针,那么当然可以这么用:**p; 这样会出什么问题呢?

    1)首先看一下p的值,p指向a[0][0],即p的值为a[0][0]的地址;

    2)再看一下*p的值,p所指向的类型是int*,占4字节,根据前面所讲的解引用操作符的过程:从p指向的地址开始,取连续4个字节的内容。得到的正式a[0][0]的值,即0。

    3)再看一下**p的值,诶,报错了?当然报错了,因为你访问了地址为0的空间,而这个空间你是没有权限访问的。

    实际上这是某一年华为的面试题。感兴趣的还可以把a的类型定义为char类型的二维数组,看看会发生什么。

    4. 二维数组和二级指针相关的参数匹配

    5. 那么问题来了,下题答案是?

    6. 关于二维数组,例如a[2][3]

        a和a[0]的值一样,首先a[0]是一个一维数组(数组的数据类型是整数),也是一个指针常量,1:该指针的值是数组第一个元素的地址,2:指向的数据类型是整数。所以a[0]=&a[0][0]。a呢,也是个数组(该数组数据类型是一维数组),a同时也是个指针常量,1:该指针的值等于该数组第一个元素的地址,该数组第一个元素是a[0](a[0]本身也是个一维数组),a[0]的地址是什么呢,a[0]是个数,该数的数据类型是一个大小为3的整数一维数组。所以a[0]这个数,内存大小是12个字节,数的首地址是xxx。该首地址也即是a[0]这个数组的第一个元素a[0][0]的首地址,(注意:a[0]和a[0][0]也都是数,而且它们的(首)地址相等,区别是他们的数据类型不一样,a[0]这个数的数据类型是一维数组,a[0][0]这个数的数据类型是整数,数据类型不相等往往大小也不想等,也有时候大小相等),所以a这个指针常量的值a=&a[0][0]。2:a指向的数据类型是一维数组,所以a+1内存移动12个字节(移动一个a所指向的数据类型这么大)。

      数组就是个指针常量,指针常量就是代表一个数组。这是从*(p+n)恒等与p[n]得出这条的。在大多数情况是对的。只在sizeof()和&运算符下,此时不等价。在sizeof()和&(取地址)里,系统把int a[5] 的a不看成指针常量而是看成是一个变量(数),数据类型为一维数组的变量(数)。显然该变量的大小是20个字节,且该变量的地址,即&a是a的变量类型(数组)的第一个元素的地址即&a=&a[0]。所以&a也是合法的。现:int a[5],int *const p=a;那么a和p在大多数情况是等价的,只有在sizeof()和取地址&运算符下不一样。sizeof(a)=20,sizeof(p)=4。&a=&a[0],&p!=&p[0]。此时a不是一个指针常量而是一个数据类型为一维数组的变量。。。。。这也是由于程序中不保存数组的大小

     参考资料:http://blog.csdn.net/wu_nan_nan/article/details/51741030

         http://blog.sina.com.cn/s/blog_5c6f793801019t3t.html

  • 相关阅读:
    Blank page instead of the SharePoint Central Administration site
    BizTalk 2010 BAM Configure
    Use ODBA with Visio 2007
    Handling SOAP Exceptions in BizTalk Orchestrations
    BizTalk与WebMethods之间的EDI交换
    Append messages in BizTalk
    FTP protocol commands
    Using Dynamic Maps in BizTalk(From CodeProject)
    Synchronous To Asynchronous Flows Without An Orchestration的简单实现
    WSE3 and "Action for ultimate recipient is required but not present in the message."
  • 原文地址:https://www.cnblogs.com/smile233/p/8361868.html
Copyright © 2011-2022 走看看