`
fantaxy025025
  • 浏览: 1328243 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类

朝花夕拾-C语言指针定义和数组定义的歧义问题-指针和数组疑难辩证-终极解答2

 
阅读更多

=

=

=

朝花夕拾-C语言指针定义和数组定义的歧义问题-指针和数组疑难辩证-终极解答2

这一篇主要目标讲多维数组和指针类型。

 

原理1:C语言中只有一维数组。2维数组可以看成是一维数组的一维数组。多维数组以此类推。

原理1:C语言中只有一维数组,:数组名称后面跟着的第一个数字维度就是数组的真实维度。除此之外,其他的参数则是数组元素的信息描述。

C语言中只有一维数组,而且数组的大小必须在编译时期就确定下来(旧标准)。然而,C语言数组的元素可以是任意对象,包括数组。这样就给多维数组的实现或者仿真提供了可能。

2维数组: int a[2][3];

分解为一维数组的代数法为:

a的1维类型为:int a[];

a[i]的类型为 int B[];

结合起来看,a的类型为:a[][3]。【从高级语言来看,a的类型为a[][],但是c语言要求写类型的时候,后面维数写确定。】

 

 原理2:不同的指针类型也是不同类型,也是不能互用的,切记别以为都是指针,就属于一个类型了:

一定要重视指针类型,这一点往往刚学的时候容易忽略。

不同的类型是不能互用的(强制转换不算)。例如int和float是不能互用的。

同理,不同的指针类型也是不同类型,也是不能互用的切记别以为都是指针,就属于一个类型了

不同的指针类型,其指针使用方法遵从指针原理(比如:指针加法减法),其取值使用方法遵从指针类型(比如int **p类型的指针,**p取到int值,遵从int的操作)。

类型有强制转换的需求指针类型,应该也可以强制转换,比如可以把p强转为:float *p8 = (int *) p;

 

原理3:指针和数组的关系,在多为数组上的应用,以2维数组为例:int a[m][n],a的类型为int (*)[n],a的类型不是int *。

int a[2];

//a是指向a[0]的地址,指针类型为 int *;

//a等价于指针 int *

 

int a[2][3];

//等价于int A[2];

//a是指向A[0]的地址,指针类型为int A[]等价于int *A,

//而A[0]的类型为int[3]等价于int *,所以a等价于类型:int (*)[3];【注意不是(int *)[3]】。

 

//根据括号左移法则(见上一篇),a的类型是int[][3], 等价于指针类型是int[3] *,因为c语言要求[3]在后面,所以只能写为 int (*)[3]   【注意不是(int *)[3]】。

//如果全用指针来看,a的类型应该是int * *。推理:a的类型是int *A,A的类型是int *,所以合并为 int *(int *)==int **。

 

知晓了上面的原理,我们来看看容易混淆的地方。

int a[m][n];

a永远是指向a[0]的地址。//不是a[0][0]的地址。原理是C语言本质只有一维数组。

a+i,指向了第i行的(首)地址。//不是a数组中第i个元素。

*(a+i)==a[i]//为什么a[i]不是(a+i)而是*(a+i)?因为a的类型和a[i]的类型是不同的。a+i的类型依然和a的类型一样是int (*)[n],而a[i]的类型确实int *。

这里的核心是a的类型和a[i]的类型是不同的。

 

a[i][j]的不同表示法:

(*(a+i))[j];

*(      (*(a+i))+j    )

*(a[i] + j)

 

*的作用:

*定义指针。在定义时,用来定义某个类型的指针。

*指针取值。在使用时,用来取值指针指向类型的值。

 

为什么可以把二维数组当成一维数组?以及为什么a指向了a[0][0]的地址?

虽然指针类型是不同的,不能混用。但地址值却只是一串数字,是可以根据情况使用的。

int a[m][n];

a指向的是a[0]的地址,而a[0]指向的是a[0][0]的地址。

问题就出在a[0]并不真实的存在,不存在a[0]这个中间变量,只是编译器根据指针类型编译的时候使用的。

所以在c中,a存储的就是a[0][0]的地址,如果a[0]这个中间变量存在,就不是这样的结果了。这就是c中很麻烦的地方。

比如a[0]真实存在,那么就成了下面的形式:

a = &a[0];

a[0] = &a[0][0];

这完全不是一回事。

 

可以说,c和指针,确实存在设计问题。这就导致c语言很多混淆难懂不好用。高级语言之所以高级,就在于对人友好。

 

好了,既然a真实存储了a[0]的地址,那么这个地址值是怎么用都可以的。

比如定义一个一维指针:int *p = a; 等价于int *p = &a[0];等价于int *p = &a[0][0];

因为p是一维指针,那么就可以完全把p当成一维指针用,因为p就是这么用的。

而c内存分配,以连续分配,则可以把p移动完所有的数组值。

具体见下面的代码:

  printf("把二维数组当成一维数组使用的原理:\n");
  int *p = a;
  for(i = 0; i < 2; i++){
    for(j = 0; j < 3; j++){
      printf("%d, ", *(p++) );
    }
  }

 

例子代码:

复制代码
#include <stdio.h>

int main(void){
  int a[2][3];

  //init
  int i = 0, j = 0;
  for(i = 0; i < 2; i++){
    for(j = 0; j < 3; j++){
      a[i][j] = i + j;
    }
  }

  //traverse
  for(i = 0; i < 2; i++){
    for(j = 0; j < 3; j++){
      printf("%d, ", a[i][j]);
    }
  }

  printf("\n");

  printf("把二维数组当成一维数组使用的原理:\n");
  int *p = a;
  for(i = 0; i < 2; i++){
    for(j = 0; j < 3; j++){
      printf("%d, ", *(p++) );
    }
  }

  printf("\n");

  printf("取值的不同方法:\n");
  printf("%d \n", a[1][2]);
  printf("%d \n", *(*(a+1) + 2)  );
  printf("%d \n", (*(a+1))[2] );
  printf("%d \n", *(a[1]+2) );

  printf("\n");

}
复制代码

 

=

=

=

分享到:
评论

相关推荐

    Groovy-朝花夕拾-mht.rar

    "Groovy-朝花夕拾-mht.rar"这个压缩包文件包含的是关于Groovy的学习资料,特别提到了Grails框架的学习内容,以及以MHT(单一文件网页)格式呈现的资料。 Groovy语言的特点: 1. **简洁语法**:Groovy的语法比Java更...

    朝花夕拾-参考答案2015.ppt

    《朝花夕拾》作为中国现代文学巨匠鲁迅先生的一部经典散文集,长久以来吸引了无数读者与研究者的目光。通过对这部作品细致入微的分析,我们不仅能窥探到作者深邃的思想,更能体会到那个时代社会文化的脉动。这本著作...

    朝花夕拾-相关习题.docx

    《朝花夕拾》作为鲁迅先生的回忆性散文集,以其独特的文学价值和深刻的思想内涵,成为了中国现代文学史上不可或缺的一页。这部作品不仅承载着鲁迅对个人过往生活的深情回顾,而且反映出作者对于所处时代的敏锐观察和...

    python云打印实现-朝花夕拾-改良版(可以下载)支持word、excel、文本 ;图片能打开需要手动、不支持pdf

    这个“朝花夕拾-改良版”是一个特定的Python项目,旨在提供这样的功能,尤其强调对Word、Excel和纯文本文件的支持。然而,值得注意的是,该版本对于图片的处理需要手动操作,且不支持PDF格式的文件。 在Python中...

    名著导读《朝花夕拾》ppt课件PPT课件.pptx

    《朝花夕拾》是鲁迅先生于1926年创作的一部回忆性散文集,原名为《旧事重提》,其后改为现名,并首次发表于《莽原》半月刊上。鲁迅,作为中国现代文学的奠基人,其作品在小说、散文、诗歌和杂文等诸多体裁领域均有...

    朝花夕拾练习题100.pdf

    他的作品《朝花夕拾》,不仅是一部个人成长史的书写,更是一幅晚清至民国初期社会风貌的画卷,透过作者的个人经历折射出时代的变迁。 《朝花夕拾》由十篇散文组成,每一篇都是鲁迅对其生命中重要时刻的细腻描绘。他...

    《朝花夕拾》名著试题答案.pdf

    2. 《朝花夕拾》作品分析:《朝花夕拾》最初发表时题为《旧事重提》,包含10篇回忆性散文,不仅表达了作者对往昔温馨记忆的怀念,同时也有对现实社会的理性批判。其中,《从百草园到三味书屋》和《阿长与山海经》被...

    朝花夕拾阅读汇报课.ppt

    朝花夕拾阅读汇报课.ppt

    名著导读《朝花夕拾》ppt课件_1PPT课件.pptx

    《朝花夕拾》是鲁迅先生的一部回忆性散文集,收录了鲁迅在不同时期创作的十篇散文。这部作品不仅是中国现代文学史上的经典,更是鲁迅个人思想与情感的重要载体。以下将详细解析其中的主要内容和主题思想。 1. **...

    鲁迅《朝花夕拾》中考名著习题及答案.doc

    《朝花夕拾》是鲁迅先生的一部散文集,收录了他回忆童年、少年和青年时期经历的文章。这部作品以其独特的艺术风格和深刻的思想内涵,成为了中国现代文学的经典之作。 在《朝花夕拾》中,我们可以看到鲁迅先生对童年...

    朝花夕拾考题+全部答案.docx

    《朝花夕拾》是鲁迅先生于1926年创作的一部回忆性散文集,共收录了十篇文章,包括《从百草园到三味书屋》、《阿长与&lt;山海经&gt;》等,这些文章反映了鲁迅先生的童年生活和成长历程,同时也揭示了封建社会的各种问题。...

    1朝花夕拾-压缩——学习ppt课件

    1朝花夕拾-压缩——学习ppt课件

    朝花夕拾鲁迅作品读书感受.pdf

    朝花夕拾鲁迅作品读书感受.pdf

    读后感500字-鲁迅《朝花夕拾》读后感范文500字8篇_朝花夕拾》读后感范文大全.docx

    根据提供的文档信息,这里主要涉及的是鲁迅先生的散文集《朝花夕拾》以及不同读者对其的读后感。尽管标签部分标注了“安全管理”,但从上下文来看,这部分内容显然与《朝花夕拾》及其读后感有关,与IT或安全管理领域...

    朝花夕拾考题全部答案.doc

    《朝花夕拾》是鲁迅先生的一部回忆性散文集,收录了他1926年创作的十篇文章。这部作品不仅描绘了鲁迅个人的成长历程,同时也揭示了晚清至民国初年中国社会的各种现象和问题。以下是根据提供的部分内容提炼出的知识点...

    《朝花夕拾》读书汇报会主持稿.doc

    《朝花夕拾》读书汇报会主持稿.doc

    2021年朝花夕拾读后感1500优秀.pdf

    2021年朝花夕拾读后感1500优秀.pdf

    《朝花夕拾》中考试题答案知识梳理.pdf

    《朝花夕拾》中考试题答案知识梳理.pdf

    朝花夕拾练习题答案.doc

    【朝花夕拾练习题答案】的文档涵盖了鲁迅先生及其代表作《朝花夕拾》的相关知识。以下是根据文档内容生成的知识点详细说明: 1. 鲁迅是中国现代伟大的文学家、思想家和革命家,原名周树人,字豫才,籍贯为浙江绍兴...

    《朝花夕拾》知识点测试题及答案精练.doc

    《朝花夕拾》知识点测试题及答案精练.doc

Global site tag (gtag.js) - Google Analytics