zoukankan      html  css  js  c++  java
  • C——数组与指针

    多维数组

     

    1.       对两维数组的理解

    对于Float rain[5][12],把它理解为有这样一个数组,它的可以表示为rain[5],而其中的每一个元素(总共有5个)是另外一个数组,这个数组有12float类型的数据。

    所以rain的首元素rain[0]是一个包含12float数值的数组,且rain[1],rain[2]等等也是如此。换言之,rain是包含5个元素(每一个元素又是包含12float数的数组)的数组。

     

    2.       对于两维数组的地址计算

    根据刚才的分析,可以得出以下结论。

    如果有数组int a[3][3], 32位机子上运行,且假设a的地址为2000,那么a[1]的地址就是20122000 + 4 * 3),而且a[1]的地址就是a[1][0]的地址,正如a的地址就是a[0][0]的地址(数组名其实就是该数组首元素的地址)。

    另外,a[2][1] == *(*(a + 2) + 1) , 理解两维数组的关键是a[1]是个int *型指针,因为a[1]是指向其首元素a[1][0]的指针,而a[1][0]int * 型。

     

    3.       如何将数组作为参数传递到函数

    处理数组的函数其实使用指针指针作为参数的。在C中,a[i]在后台就是被解析为*(a + i)

    (1)     一维数组

    方法一,如果有float a[3],那么对应的函数原型至少为 int sum(float * a, int n),其中float * a 是因为以后将会传入数组名,而数组名就是数组第一个元素的地址,所以要与之匹配,对于这个例子,数组的第一个元素是float型,所以如果传入参数的话就应该是float*. int n是为了传入这个数组的大小,防止函数内越界。

     

    方法二,如果有float a[3],那么对应的函数原型至少为 int sum(float * a, float * end)

    调用如下 sum(a , a + 3)。然后需要在sum中做的事情是判断,注意在做while的时候的判定条件是 while ( a < end),其中千万不能用等号,因为a的最后一个元素为a[2]

     

    (2)     两维数组

    利用指针数组(形似int (*p)[2],函数原型写成 int sum( int (*p)[2], int rows)。其中要已知两维数组的列数为2,行数作为一个参数传进sum.

     

    4.       指针可以使用的基本操作

    (1)       赋值

    (2)       求值(*操作符)

    (3)       取指针的地址(&操作符)

    (4)       将整数加给指针(包括自加)

    (5)       从指针中减去一个整数(包括自减)

    (6)       求差值——通常对分别指向同一个数组内两个元素的指针求差值,以求出元素之间的距离。

    (7)       比较——前提是两个指针具有相同的类型

     

    5.       对指针的加减法运算

    C中,对一个指针加1的结果是对该指针增加1个存储单元(即它所指向的对象的字节大小)。比如说有int * p. 如果p的地址是2000,那么++p的结果是2004(在32位机子上,int占用4个字节)。

    对于数组而言,由于这个特性,地址会增加到下一个元素的地址。

       于是,如果有double dates[10],则显然 (date + 2) == &dates[2],而且*(dates + 2) == dates[2]

     

    注意,这里是对指针的加减法,虽然dates代表dates[0]的地址,但是它毕竟不是指针,而是地址的常量。所以语句dates++是违法的。

     

    6.       关于const int * pint  * const p

    前者constint *, p所指向的地址是不能够被改变了,但是这个地址所代表的内容却是可以改变的。后者constp,即p的内容(*p)是不能够被改变了,但是p所指向的地址却是可以转换的。

     

    7.       指针数组与数组指针

    关键在于[]的优先级高于*

    (1)     Int (*pz)[2]

    pz是一个指针,指向一个int[2]的匿名数组。

     

    (2)     Int * pz[2]

    Pz是一个数组,他有2个元素,而且每一个元素是int *型。

     

    8.       指针的兼容性

    指针赋值非常严格,只能够赋给相同类型的值。

    例如有如下声明:

    Int * pt;

    Int (*pa)[3];

    Int ar1[2][3];

    Int ar2[3][2];

    Int **p2

    那么有如下结论

    Pt = & ar1[0][0] //成立

    Pt = ar1[0] //成立 ,因为ar1[0]就是int * 型指针。可以这样理解。 &Ar1[0][0] == *(ar1 + 0) + 0

    Pt = ar1 // 非法,因为ar1是指向由3int值构成的数组的指针,说白了其实是一个int[3]型的指针,而不是int *型指针。Ar1是指向ar1[0]的指针,而ar1[0]是一个int[3],所以ar1int[3]型指针。

    Pa = ar1 // 成立,理由见上

    Pa = ar2 //不成立, 因为paint[3]型指针,而ar2int[2]型指针

    P2 = &pt //成立

    *p2 = ar2[0] //成立,因为ar2[0]int * 型指针,因为ar2[0]是指向其首元素ar2[0][0]的指针

    P2 = ar2 //不成立,p2int **,ar2int[2]型指针。

  • 相关阅读:
    服务部署 RPC vs RESTful
    模拟浏览器之从 Selenium 到splinter
    windows程序设计 vs2012 新建win32项目
    ubuntu python 安装numpy,scipy.pandas.....
    vmvare 将主机的文件复制到虚拟机系统中 安装WMware tools
    ubuntu 修改root密码
    python 定义类 简单使用
    python 定义函数 两个文件调用函数
    python 定义函数 调用函数
    python windows 安装gensim
  • 原文地址:https://www.cnblogs.com/aicro/p/1580084.html
Copyright © 2011-2022 走看看