精华内容
下载资源
问答
  • int main ( ) { char a[2][3]={ {1,2,3} , {4,5,6} } ; char (*p) [3]; p=a; printf (“%d , %d , %d , %d ,%d ”, a , &a, *a, **a, *(*(p+1) + 2));  return 0; } ...貌似很简单的个题
     int   main (  )
    {
       char  a[2][3]={ {1,2,3} , {4,5,6} } ; 
       char   (*p) [3]; 
        p=a;
       printf (“%d , %d , %d , %d ,%d ”, a , &a, *a, **a,  *(*(p+1) + 2)); 
       return   0;
    }
       请问输出该是多少?貌似很简单的一个题目,却不觉得让人看得有点头大。如果您已能很清晰地理解本题的话,那就无需再浪费您的时间了,请继续飘过吧…如果觉得有点疑惑的话,且听我细细道来。如果哪里说错了还请指正。
       先讨论下这个问题:char *pC; 假设此时pC里面的值是0x00012,如果pC++,那么pC会是多少呢?很显然是0x00013对吧。如果是int *pInt;也假设pInt 的值是0x00012,那么pInt++后的值就应该是0x00016了吧......关于这个问题你可以简单的理解为是由于地址对齐的缘故!说了这么多,我只想说,如果想看看某个指针指向的空间占多少字节,可以用这个方法。接下来用这个方法解释下面这些问题。
    
       且看第一句,这句很显然没问题,是人都知道这不过是定义了一个二维数组,两行三列,并且分别给它们赋值而已。大家一看就知道,a就是这个数组的首地址,这个每本书每个老师都是这样说的,虽然不知道为什么……
    
       第二句嘛,咋一看有点像个数组,可是括号里面却有个*p。好像比较少见。不急,大家可以联想到:char  * p [3] ; 有眼睛的一看就可以看得出来,这只不过把括号给去掉了。好吧,我就看上面没有括号的那句,很显然,这句绝大多数人看一眼就知道这其实就是个指针数组,也就是:(char *)  p[3] ; 跟普通的数组没啥区别,只不过这个数组里面每个成员都是个char *类型的字符指针。对没错,可是加了个括号呢?char  (*p)  [3]又表示什么呢?好,如果你开始觉得有点模糊了,那么你很正常,因为我刚开始也是这样的。再看看下面这两句:typedef  char   p_Char[3];    p_Char  *p; 这句中的p表示什么呢?也许你还不是很清晰,但你应该可以确定是个某种类型的指针。如果你对这里的typedef的用法不太了解的话,那么也许你应该去百度一下关于typedef的用法,这里就不说了,我只告诉你此处的p跟上面的char  (*p)[3] 是完全一样的效果。也就是说此处并不是定义数组,而只是个指针,而这个指针指向的变量不是普通的char,而是一个有三个元素的数组。你可以试试看sizeof(p)的值是多少,结果应该是4吧,会是个数组吗?你还可以输出一下p和p++的值,看看它们相差多少?应该是3吧!
    
       这第三句就更简单了,一个简单的赋值语句,把二级指针a(也就是二维数组的首地址)赋值给p(也是个二级指针)。
    
       第四句就是个输出语句,我们直接看后面的参数,a的值应该是数组的首地址吧,&a好像没这种用法,你有见过吗?如果你怀疑编译器会报错的话,你大可一试,至少我在VC6.0上面可以通过。a本身就是个地址,再取地址会是什么呢?也许你是这样想,不奇怪,我也这样想。再看看*a这个也可以理解,a是个地址嘛,*a也就是a这个地址里面的值咯。好像说的也没错。
    
       好吧,上面对那个小程序的一点分析只不过是个引子,接下来才是我真正要说的。我们来想想学了C语言后,一共有多少种数据类型呢?从int、short、long、double、char、char*、到char a[3],到int aa[5],再到struct a{ int a, char c; } aa ;我们可以看到可以共可分为三种,第一是最基本的类型,比如:int、short、char等......第二是在最基本的类型上扩充而来的,也就是数组,由多个相同类型组成的,第三种则是由不同的类型组成的,也就是结构体。
    
       我们再来看看如下情况:int  a;  char b[5];  struct a  aa; 至于这是什么,也许你应该去看看谭浩强的C语言。那a、b、aa、的值分别是什么呢?当然这里并不关心它的真正值,只是想说明它们分别表示什么!很显然,a的值就是编译器在堆栈里面分配的4个字节空间里面的内容,aa也类似,但是b呢?b本应该也表示这5个字节里面所表示的内容,也就是说b本应该代表从b[0]到b[4]这几个空间里面的内容,但是需要注意的是因为它是数组,所以实际上编译器给出了单独的例外处理:当某处引用数组名字的时候并不代表数组里面的所有内容,而是代表了该数组的首地址。这说明:当我们用数组名字的时候要注意,一般情况,把它理解为地址,如果是形如“&  数组名”则还可把数组名看做数组整体内容。我们可以跟上面的a和aa对比一下,对于普通的a很显然,当引用a的时候我们就理所当然的以为是该空间里面所包含的内容,当我们引用结构体变量名的时候我们也理所当然的把他当做该结构体所占空间里面的内容,对于数组,按照我们刚才的那种思维逻辑,数组名其实也是代表这个数组里面真正包含的内容,而不是其首地址。是的我们本应该这样理解。但实际情况则不同,编译器不会这样做。这就是为什么我们老师苦口婆心不厌其烦地告诉我们数组名就是首地址的缘故了。所以回到刚开始那个问题,用我们上面的话说,&a中的a可以表示的是整个数组内容,所以取其地址还是数组地址,当然此时的a也可以理解成地址,但由于a是个二维数组,也就是个二级指针,那么&a就应该是个三级指针了。所以如果要把&a赋值给某个指针变量的话,那它应该是形如char  (*p)[2][3]类型的变量了;  *a表示的是什么呢?这个问题也很让人纠结......是表示数组的第一个元素的值吗?你可以试试,本题结果还是地址。为什么呢?接下来才是本文要说明的核心。
    
       相信大家都知道,一个一维数组的数组名是个一级指针,而二维数组的名就是个二级指针,三维数组的名字就是三级指针......以此类推。我是不知道您是怎么理解二级指针和三级指针的,在我看来,所谓二级指针其实也是个指针,只不过它指向的空间必须是个一级指针,而该一级指针指向的空间就是真正要指向的那个变量地址。也就是说一维数组名是个一级指针,那么对于char  C[2]={1,2}; 因为C是个一级指针,所以&C就应该是二级指针了。C可以赋值给char *p类型的变量,而&C却只能赋值给char  (*p)[2];类型的指针,注意此处的p也是个二级指针。这时你可以用上面的方法试试C+1和C的值相差多少个字节?应该是大2吧!*C的值就应该是数组的第一个元素的值了。对于二维数组char C[2][3]= { {1,2,3 },{4,5,6 } };C是个二级指针,你也可以试看看C+1和C究竟差了多少个字节?应该是6吧!既然C是个二级指针也就是说*C是个一级指针,虽然指向的地址和C指向的地址是同一个,但是此时表达的意义就大不一样了。C是个二级指针,而且它指向的范围是从1~6,而*C是个一级指针,范围从1~3,你可以试试(*C+1)和*C相差多少?应该是3吧!。那**C呢?很显然一级指针指向的空间就不会是地址了,而应该是地址里面的内容了,也就是1。对于三维、四维等情况都是类似的,以此类推.....
    
       最后我们来看看 *( *(p+1) +2 )的值会是多少?首先p是个指针,里面存放的地址是一个char[3]类型的地址,而p又被赋值了a,所以p+1就应该指向下一个char[3]类型的地址,也就是指向了a数组的第二行首地址,*(p+1)很显然就是指数组a的第二行里面的内容,根据刚才的分析,如果是数组的话,一个表示数组整体内容的其实就是用其首地址来表示,所以*(p+1)表示的是数组a的第二行的首地址,然后*(p+1) +2 表示的就是第二行的第二个地址,最后*(*(p+1) + 2)表示的就是第二行的第二个地址所存放的内容,也就是6。
    
       貌似我把一个很简单的问题说了很多,接下来我要问问几个问题看看你究竟理解了我说的没有,请看下题:
    对一维数组:char  C[3];,请问如何定义一个指针变量P0,使得这句:P0=C;能通过编译?如何定义一个指针变量P1,使得P1=&C能通过?*C表示什么?
    对二维数组:Char  C[2][3];如何定义一个指针变量P0使得P0=C;能通过编译?如何定义指针变量P1使得可以P1=&C; *C表示什么?**C又表示什么?这些有啥区别和联系?
    后面的我就不多说了,如果你能很清晰的理解这些东西,那么你就懂了,否则那就请把本文再从头看一遍吧!
    
    展开全文
  • 二维数组与一维数组指针变量的关系  1. 如 int a[5][10] 与 int (*p)[10];  2. 二维数组名是一个指向有10个元素的一维数组的指针常量  3. p=a+i 使 p指向二维数组的第i行  4. *(*(p+i)+j)  a...

     二维数组与一维数组指针变量的关系


             1.      如   int  a[5][10]  与  int   (*p)[10];
             2.      二维数组名是一个指向有10个元素的一维数组的指针常量
             3.      p=a+i  使 p指向二维数组的第i行
             4.       *(*(p+i)+j) < = > a[i][j]
             5.      二维数组形参实际上是一维数组指针变量,                   

             6.      即   int  x[ ][10]  < = > int  (*x)[10]
             7.     变量定义(不是形参)时两者不等价
             8.     系统只给p分配能保存一个指针值的内存区(一般2字节);而给a分配2*5*10字节的内存区

    展开全文
  • 指向具有M个元素的一维数组指针 注意:指向的是一维数组,而不是之前提到的指向一维数组的某个元素!!! 定义格式: 类型名 (*变量名)[M] ; 注意:M是一维数组的元素个数,类型名是一维数组的元素类型。 ...

    指向具有M个元素的一维数组指针

    注意:指向的是一维数组,而不是之前提到的指向一维数组的某个元素!!!

    定义格式: 类型名 (*变量名)[M] ;

    注意:M是一维数组的元素个数,类型名是一维数组的元素类型。

     

    用途:通常利用该指针变量,指向二维数组的行地址,其中M表示二维数组的列数。

    举个例子:利用行指针变量,按照行输出二维数组各个元素值。

    方法一:

     

    方法二:

    请记得:

    a是该二维数组第一行的行地址,即&a[0]。

    a+1是该二维数组第二行的行地址,即&a[1]。

    a+2是该二维数组第三行的行地址,即&a[2]。

    而:

    a[0]是数组第一行元素的首地址,或者叫第一行第一列元素的地址,即&a[0][0]。

    a[1]是数组第二行元素的首地址,或者叫第二行第一列元素的地址,即&a[1][0]。

    a[2]是数组第三行元素的首地址,或者叫第三行第一列元素的地址,即&a[2][0]。

     

    字符串指针:是字符串的首地址,即第1个字符(索引为0)的地址。使用char型指针变量存放其首地址。

    注意:

    展开全文
  • 在我上大三的时候,有段时间发现自己对指针的理解不够深入,所以就看了《Pointers On C》这本书的指针章节,当时印象很深刻的是接触到了一维数组指针这个概念,最近我在看内核代码时又遇到了这个问题,结果一时间...

    在我上大三的时候,有段时间发现自己对指针的理解不够深入,所以就看了《Pointers On C》这本书的指针章节,当时印象很深刻的是接触到了一维数组指针这个概念,最近我在看内核代码时又遇到了这个问题,结果一时间竟然没看懂,搜了资料才想起来这么个概念。

    举个例子:

    #include<stdio.h>
    
    void main()
    {
        int boot_gdt[] = {1,2,3};
        int *a = boot_gdt;
        int *b = &boot_gdt;
        printf("%x\n",a);
        printf("%x\n",b);
    }

    两个输出语句会输出同样的结果,一开始我大为不解,后来看到了这个资料:https://stackoverflow.com/questions/2528318/how-come-an-arrays-address-is-equal-to-its-value-in-c/2528328#2528328

    看完这个答案后我恍然大悟,原来 a 是数组元素的指针,其值等于数组起始地址,而 b 是整个一维数组的指针,其值也等于数组的起始地址。虽然两个地址值在数值上相等,但是其意义完全不同。指针变量做加减运算时,其地址值的变化是以其指针指向的数据类型大小作为跨度的,a+1 这个指针指向了数组元素 boot_gdt[1],但是 b+1 这个指针则指向了下一个数组。举个例子,如果数组起始地址为 0x0,即 a 的地址值为 0x0,那么可以得出 a+1 的地址值为 0x4,而 b+1 的地址值则为 0xc。可以清晰的看出,元素指针 a 每次加一时,其地址值一次跳 4 个字节,而一维数组指针 b 每次加一时其地址值一次跳 12 个字节,也就是跨越了一整个数组的大小。

    展开全文
  • 指向一维数组元素的指针变量,指向一维数组指针变量 指向指针指针变量(**p):顾名思义,由于指针运算符的右结合性即 *(*p) 第一个指针只向的是一个地址,然后第二个指针指向的才是地址中的值。 指向一维...
  • 一维数组指针[num和&amp;num的区别] #include&lt;stdio.h&gt; #include&lt;stdlib.h&gt; void main() { int num[10] = { 1,2,3,4,5,6,7,8,9,0 }; int *p = num; int(*pa)[10] = num; ...
  • 文章目录一维数组指针和二维数组指针的定义一维数组指针和二维数组指针用于索引数组元素一维数组指针和二维数组指针的可视化解读 一维数组指针和二维数组指针的定义 一维数组指针的定义就是普通指针的定义 指针变量...
  • C++一维数组指针详解

    2020-04-13 09:41:48
    int main() { int a[5]={1,2,3,4,5};...a[0],此时p1是数组a的第个元素的地址 cout<<*p1<<endl; //输出a[0] cout<<*(p1+1)<<endl; //输出a[1] int (*p2)[5]; p2=&...
  • 字符串指针与一维数组指针的区别

    千次阅读 2010-10-26 11:52:00
    字符串指针与一维数组指针有很多共同点,但也有一些区别: 1、赋值有要求。  我们可以在程序中将一个字符串赋给一个字符串指针变量,但不可以将一个字符串赋给一个数组名。即: 允许:char *...
  • 1】一维数组与指针 2】二维数组与指针 3】指针数组 4】数组指针 5】二级指针 1】一维数组与指针: #include <stdio.h> #include <stdlib.h> #include <string.h> int main...
  • 今天偶尔帮别人做C语言题,突然 想写篇C语言的数组指针,指针数组还有二维数组用指针表示,以后自己忘了就可以直接看博客了。 数组指针:是个指针,指向个数组 int a[5]={1,3,5,7,9}; int *p=a; int (*...
  • 我们知道,对于一维数组,其数组名可以理解为一个特殊指针,具有常量的性质,使用sizeof可以求得数组的长度,而当作为函数参数时,就退化为一个指针,此时sizeof不再能求得数组的长度了。一维数组名可以直接赋给一个...
  • 一维数组 int a[]={1,3,5} a:数组首行首元素地址,一级指针 &a:整个数组的首地址,二级指针 a+1:跳4个字节 &a+1:跳12个字节 sizeof(a) :取的是整个数组长度12字节 sizeof(a[0]):取的是数组首元素,4字节 ...
  • 维数组与指针、指针数组、数组指针的用法

    万次阅读 多人点赞 2018-03-12 18:16:20
    二维数组和指针⑴ 用指针表示二维数组元素。要用指针处理二维数组,首先要...而每个大数组元素对应二维数组的一行,我们就称之为行数组元素,显然每个行数组元素都是一个一维数组下面我们讨论指针和二维数组元素的...
  • ()优先级高,首先说明p是一个指针,指向一个整型的一维数组,这个一维数组的长度是n,也可以说是p的步长。也就是说执行p+1时,p要跨过n个整型数据的长度。如要将二维数组赋给一指针,应这样赋值:int a[3][4];int (*...
  • 一维数组 指针形式 赋值指针 含义 int obj[5] obj int *pz;pz=obj; 指向一个int类型的指针 二维数组 指针形式 赋值指针 含义 int obj[5][4] obj int (*pz)[4 ](数组...
  • C语言二维数组指针(指向二维数组的指针)详解

    千次阅读 多人点赞 2020-05-27 17:43:22
    如有需要,请访问C语言二维数组指针(指向二维数组的指针)详解 二维数组在概念上是二维的,有行和列,但在内存中所有的数组元素都是连续排列的,它们之间没有“缝隙”。以下面的二维数组 a 为例: int a[3][4] = { ...
  • 概念详解:指针指针与“int a”,...一维数组:定义一维数组之后,即在内存中分配一段连续的地址空间,如C语言中,int num[5],在32位系统中,int占据4个字节,现假设num[0]的地址空间为0x00000004,那么num[...
  • 指针变量可以指向一维数组中的元素,当然也就可以指向二维数组中的元素。但是在概念和使用方法上,二维数组的指针一维数组指针要复杂一些。要理解指针和二维数组的关系首先要记住一句话:二维数组就是一维数组,...
  • 1.一维数组的地址 在C语言中,数组名是个不占内存的地址常量,它代表整个数组的存储首地址。 一维数组元素a[i]的地址可以写成表达式&a[i]或a+i,&a[i]是用下标形式表示的地址,a+i是用指针形式表示的地址,...
  • (*p)[n]:根据优先级,先看括号内,则p是一个指针,这个指针指向一个一维数组,数组长度为n,这是“数组的指针”,即数组指针; *p[n]:根据优先级,先看[],则p是一个数组,再结合*,这个数组的元素是指针类型,共...
  • 二维数组本质是也是线性存储的一维数组,各元素都是相对于基地址(首地址)的偏移,只是逻辑上的维度区分而已。...多维数组可以降维来处理,一个n维数组通过一个n-1维数组指针或指针数组(其元素的指针...
  • LOGO 数组与指针一维数组地址和指针 主讲人周芸 教学目标 掌握一维数组的指针的用法 理解一维数组指针的本质 具备应用一维数组指针编程的能力 张丽去排队打疫苗医生通过叫号的方式依次注射 引入 一指向一维数组的...
  • 今天偶尔帮别人做C语言题,突然 想写篇C语言的数组指针,指针数组还有二维数组用指针表示,以后自己忘了就可以直接看博客了。 数组指针:是个指针,指向个数组 int a[5]={1,3,5,7,9}; int *p=a; int ...
  • 维数组指针

    2019-08-06 05:17:22
    关于一维数组的指针 ...一维数组指针就是该一维数组第一元素的地址,取值运算*结果是第一个元素存储值。 再看二元数组 例子: int v[2][5]={{1,2,3,4,5},{6,7,8,9,10}}; int (*a)[5]=v; printf("%p,%p\n",...
  • 二维数组本质是也是线性存储的一维数组,各元素都是相对于基地址(首地址)的偏移,只是逻辑上的维度区分而已。...多维数组可以降维来处理,一个n维数组通过一个n-1维数组指针或指针数组(其元素的指针...
  • 如果数组中的所有元素保存的都是指针,那么我们就称它为指针数组。 除了每个元素的数据类型不同,指针数组和普通数组在其他方面都是一样的,下面是 个简单的例子: 1. #include &amp;lt;stdio.h&...
  • 1. 下面是为一维数组 / 二维数组 / 三维数组 动态分配内存 实现的代码: // 一维数组动态申请,a数组大小为: n int *a = new int[n]; // 二维数组动态申请,b数组大小为: n*p int **b = new int*[n]; ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 8,744
精华内容 3,497
关键字:

一维数组指针