第八章 指针(上)
地址和指针的基本概念
内容可变,地址不可变
有了变量的地址,存取变量就可以通过两种方式
- 通过变量名
- 通过变量的地址
// 指针变量
int *p;
// 变量类型 int *; 变量名为 p
// 指针变量一律占4个字节
基类型
指针变量所指向的变量的类型
int a = 1;
double b = 8.2;
int *p;
double *q;
void *r;
// p为int *型,只能指向int型
p = &a;
// q为double *型,只能指向double型
q = &b;
// r为void *型,可以指向任何类型
r = &a;
r = &b;指针变量的赋值
指针变量值为0(地址值为0)时,表示什么也不指向 - 空指针。【地址值为NULL也表示空指针】
int a = 1;
int *p;赋值语句的方法
p = &a;定义指针变量时初始化(定义时赋初值)
int b = 2;
int *q = &b;允许指针变量之间赋值,但另两个指针变量必须基类型相同
q = p;
int *r;
r = q;特殊情况
int *p;
// 下面两种情况都表示空指针
p = 0;
// NULL(全大写),系统定义的宏 #define NULL 0
p = NULL;两运算符(&, *)
&取地址运算符
获取变量的地址,用法:&变量名
*指针运算符(间接访问运算符)
获取或改写以p为地址的内存内容
*p,*不是获得或改变指针变量本身的值,而是获得或改写它所指向单元的值。
int *p,*运算只能用于指针变量,不能用于普通变量(如*a错误);
&和*互为逆运算
int *p = &a;
p == &a;
*p == *&a == a;
&*p == p;
&*&*&*p == p;
*&*&*&p == a;数组的指针
指针变量的运算
指向向前或向后移动n个单元,
p+n=p中的地址编号 + (每元素字节数*n)
p-n=p中的地址编号 - (每元素字节数*n)
概运算应只针对
指向数组的指针变量进行,否则毫无意义
int a[5] = {1,2,3,4,5};
int *p;
p = &a[1];
// p++运算后与&a[2]相等
p++;
// p+=2 运算后与&a[4]相等
p+=2;每个
char型变量占1个字节,对基类型为char的指针变量+n,恰好是地址+n
char c[4] = {'a', 'b', 'c', 'd'}
char *p = &c[2];void 类型的指针不能做+(-)n的运算(也不能++, --的运算)
指针的变量相减
两指针变量的加减乘除运算时没有意义的。
p1 - p2 = (p1中的地址编号 - p2中的地址编号)/镁元素字节数
关系运算
该运算一般只对指向同一数组的元素的两个指针变量进项,表示他们所指向元素的先后位置
// 表示p1和p2指向数组的同一个元素
p1 == p2
// 表示p1所指元素位于p2所指元素之后;
p1 > p2
// 表示p1所指元素位于p2所指元素之前;
p1 < p2// 与0和NULL比较
// 表示p为空指针
p == 0;
p == NULL;
// 表示p不是空指针
p != 0;
p != NULL;数组元素的地址转换为元素下标
int a[5] = {1,2,3,4,5};
int *p, *q;
q = &a[0];
p = &a[2];
p - a 则得2两个重要公式
语法糖
编译时编译系统将
a[i]全部变为*(a+i).
a[i]就是语法糖,便于我们理解而设计的成为语法糖。
int a[5] = {1,2,3,4,5};
a + i == &a[i];
a[i] == *(a+i)指针变量可写为数组的形式
int *p = x[0];
x[i] == *(x+i);
&x[i] == x+i;指针变量与一位数组名的统一
int a[5];
int *p;
p = a;
p = &a[0];
p[0] == *p == a[0];
p[i] == a[i];
*(p+i) == *(a+i);
p 和 a 不能互相转换
p的值(地址)可被修改,a的值(地址)不能被修改
p是变量,a是假想的“指针变量”(是常量)指针运算的优先级
&, *的优先级和++, --相同,都非常高,仅次于()
与++, --统计运算时,从右至左结合
二维数组的指针
// 行指针
int (*q)[4];
int a[3][4];
q = a; 一个表格、两句法则
| 草稿写法 | ±1效果 | 定义 | |
|---|---|---|---|
| 二级指针 | [[]] | 移动一行 | int (*q)[4]; int b[3][4]; 中的b |
| 二级指针 | [[]] | 必移动4字节 | int **r; int *s[3]; 中的s |
| 一级指针 | [] | 移动一个单位(int型4字节,char型1字节…) | int *p; int a[2]; 中的a |
| 普通变量 | 变量值±1 | int x; |
法则:
- 定义变量时:一个
*或一个[]升一级 - 使用时:一个
*或一个[]降一级;一个&升一级
两个重要公式
二维数组元素的写法
a[i][j]是*(*(a+i)+j)的语法糖
x[i] == *(x+i);
&x[i] == x+i;
a[i] == *(a+i) == q[i] == *(q+i);
q[i][j] == *(a[i]+j) == *(*(a+i)+j)==q[i][j] == *(q[i]+j) == *(*(q+i)+j);
特殊的 i=0,j=0
a[0][0] == **a;
&a[0][0] == *a;