数组
定义:数组是有序的相同类型数据的集合
- 一维数组
- 定义:存储类型 数据类型 数组名[常量表达式];
int score[5]; int score[3] = {1,2,3}; int score[3] = {1,0,0} 或者int score[ ] ={1,2,3}的不推荐做法,长度未指定
- 数组名:本质为指针,指向首地址
- 存储:①连续地址空间②数组名为首地址③数组名是地址常量,所以不能向它赋值、加减运算④超出数组范围语法上仍可以访问,但不安全!!!
- 数据传递:地址传递时,实参和形参类型必须相同。
例:int b[5] ; func(b); void func(int a[5]); 或 void(int a[]); 或 void (int a[], int len ); 或 void (int a[8]); 长度超出,虽无语法错误,但结果不符合预期
- 定义:存储类型 数据类型 数组名[常量表达式];
- 二维数组
- 定义:存储类型 数据类型 数组名[常量表达式] [常量表达式];int score[2][3]; int score[2][2]={{1,2},{2,3}}; int score [2][2]={{1};{2}};int score[1][3]={1,2,3}; in t score[1][3]={1};自动匹配必须指定列数
- 存储:①把降维到最底层的元素依次存放到一片连续空间②score[i]表示 行地址③数据名为首地址常量!
int a[2][2] ={1,2,3,4},则a[0][3] == a[1][1] ==4,因为访问数据基于首地址的偏移量,3 == 1*2+1
指针
指针是一种数据类型,它是目标对象的地址
指针的运算:<font color =red>取地址/取内容;加/减整数;相同类型指针的减法;相同类型指针的关系运算。</font>
-
指针常量:变量的地址——当变量定义后,获得计算机分配的内存,地址空间的首地址即为该变量的地址,通常称为地址常量或指针常量。
-
指针变量:可以装指针常量的变量
-
定义:<存储类型> <数据类型> *指针名;
例:int *px; char *name; static int *pa;
- 存储类型:auto、register、static、extern,存储类型和申明位置决定指针的寿命和作用域。
- 数据类型:指针所指向的目标的数据类型
- 大小:在32位系统中,指针变量在内存占4个字节。
- * 的作用:说明符,向编译器说明它后面的变量为指针
-
取地址 &:&操作对象
- 操作对象 为 变量或有名存储区,不能为数组名、常量、寄存器变量。
- 运算结果 为操作对象变量的地址
- 结果类型 为操作对象类型的指针
-
取内容 * :* 操作对象
- 操作对象 为地址表达式,即指针
- 运算结果 为指针所指的对象,即变量
- 结果类型 为指针所指对象的类型
-
’ * ’ 和 & 关系:互为逆运算
-
NULL 空指针:特殊状态,不指向任何对象
-
一维指针与一维数组:
- 相同点:访问连续存储的数据,四种等价形式
- 不同点:
①指针pa为地址变量,数组名为地址常量,常量不能赋值、加减运算!data = p; data++; data =data+3; 都是错误的
② a[i] 与 *(pa+i) 转化的大前提是 pa = a - 注意:当指针指向数组首地址时,指针变量名可以当成数组名使用; 只有指针指向数组时才能进行加、减等运算 !
-
多级指针与多维数组:
n维数组:n维看作以n-1维 数组为元素的一维数组。
n维数组的数组名是指向 n-1维数组的指针,其值为n维数组的首地址,类型为n-1维数组类型的指针。
例如:int a[2][3] ,*ptr; 二维数组可以看成2个一维数组 a[0] 和 a[1]
ptr = a; ptr指向a[0][0]元素的地址,a[0]数组的首地址,a[2][3]的首地址。
数组指针 : <存储类型> <数据类型> (*数组指针名) [元素个数];本质为指针,存放着数组首地址的地址
数组指针的应用:二维数组名为实参,对应形参为 一维数组的指针变量
指针数组:<存储类型> <数据类型> *指针数组名 [元素个数];数组的元素为指针变量,拥有相同的存储类型、指向相同的数据类型。
多级指针:<存储类型> <数据类型> ** 指针名; 指针变量指向的变量仍然是指针变量,即二级指针
int **ap,*s,num; ap =&s; s=# num =100; 则 **ap == *(*ap) == *s == num;
野指针 :常常是因为定义后未初始化,导致默认为随即地址;所以指针定义必须初始化 -
指针函数
- 定义:<存储类型> <数据类型> * 函数名 (参数表);函数的返回值是地址
注意:返回值不能是函数内部的自动变量地址和自动型数组首地址,因为生命周期结束,外部函数不能访问数据
- 函数原型说明:
int *p(); p为指针型函数,函数返回值为指针,该指针指向int型
- 应用:字符串处理
- 定义:<存储类型> <数据类型> * 函数名 (参数表);函数的返回值是地址
-
函数指针
- 定义:<存储类型> <数据类型>(*函数指针名) (参数表) [=函数名]; 函数拥有内存物理地址,函数名表示首地址,即函数的执行入口地址。
- 变量申明与初始化:
①int (*pfun) (int,int) = add;② int (*pfun)(int,int); pfun = add;
- 作用:既然可以直接用函数名调用函数,为什么还要用函数指针呢?
- 作为参数传递函数的执行地址
- 实现多函数调用,利用函数指针数组
- 注意:函数指针不能加减等算数运算,不同于数组指针;函数地址唯一,加减无意义!
指针深入辨析
- 判断级数:* 个数 和 中括号对个数 之和
- 判断目标对象:去掉 “*指针名” 的剩余部分 或者 去掉数组名和一对方括号