指针知识框架(详解)
指针知识框架(详解)
本文为 C 语言学习过程中关于指针的笔记。根据书籍和程序题并参考网络上的博客回答,撰写的感悟和收获。
文章参考:
C 语言解惑指针、数组、函数和多文件编程(作者刘振安刘燕君,机械工业出版社)
一、对指针使用 const 限定符
1. 指向常量的指针
const int y=66;
const int p=&y; // 此时 y 和 p 都不能做为左值,但可以作为右值。
使指针指向一个不可修改的常量,即 p 是常量。但是可以通过修改 p 指向的地址,改变 p 的值。
例如:
1 | const int y=66; |
由指向 y 改为指向 x,*p 被覆盖。
2. 指向常量的指针指向非常量
示例:
1 |
|
示例中指向常量的指针 p 指向变量 x, 仅限制直接使用 p 作为左值,但可以通过直接修改 x 的值改变 p 的值。同时也与使用非常量指针一样,也可以直接使用 “&” 改变常量指针的指向,显然也改变了 * p 的值。
【注】常量只能由指向常量的指针(即 const voidp)指向,否则必须进行强制转换,将常量强制转换为相应的指针类型。如示例:p1=(int)&y;
3. 常量指针
限定符 const 放在 * 号右边,是指针本身成为一个 const 指针。声明常量时必须进行初始化,即指针变量 p 存储的为常量地址。
例如:int x=45;
int * const p=&x//p 始终指向 x 的地址。但可以修改 x 地址内存的值,x=123 和 * p=123;但 p 指向的地址不能改变
4. 指向常量的常量指针
即指针和指向的对象都不能改动的 “指向常量的常量指针”。p 和 p 都是常量。限制了 “&” 和 “” 运算符,很少使用。
5.void 指针
void 类型不能声明变量,但可以声明 void 类型的指针,而 void 型指针可以指向任何类型的变量。
1 |
|
【注】但奇怪的是,测试时发现 p=(int*) vp 不加(int*)也可以正常运行。
小结
const 放在的右边(void * const p), 修饰的是指针(即指针变量 p 指向的地址)不可改变。
const 放在前端(const void * p), 修饰的是指向的对象(指针变量 p 存储的地址的值), 即 p 是常量
二、指针与数组
1. 数组与指针的关系
指向数组的指针实际上指的是能够指向数组众人一个元素的指针。
int a[5];
int *pa=&a [0];// 等同于 int *pa;
pa=a;
数组名和指针的区别:指针是变量:pa=a 或 pa 是有意义的;
数组名是指针常量:a=pa、a、pa=&a(a 本身就是地址,无法对地址取地址)是非法操作。
假设指针现在指向 a [0], 则数组的第 i 个(下标为 i)元素可表示为 a [i] 或 *(pa+i), 还可使用带下标的指针 pa, 即 pa [i] 和 *(pa+i)的含义一样。若将 a [i] 的值修改,下列语句等价。
a[i]=123; *(a+4)=123; *(pa+4)=123; pa[4]=123;
下标 | 数组名 | 指针 | 指针下标 | 四者的逻辑关系 |
---|---|---|---|---|
a[0] | a | pa | pa[0] | a[0]*a*pa==pa[0] |
a[1] | a+1 | pa+1 | pa[1] | a[1]*(a+1)*(pa+1)==pa[1] |
a[2] | a+2 | pa+2 | pa[2] | a[2]*(a+2)*(pa+2)==pa[2] |
2. 指针数组和数组指针
数组的指针:是一个指针,什么样的指针呢?指向数组的指针。
指针的数组:是一个数组,什么样的数组呢?装着指针的数组。
本质是的后面是类型。
然后,需要明确一个优先级顺序:()>[]>*,所以:
(*p)[n]:根据优先级,先看括号内,则 p 是一个指针,这个指针指向一个一维数组,数组长度为 n,这是 “数组的指针”,即数组指针;
p [n]:根据优先级,先看 [],则 p 是一个数组,再结合,这个数组的元素是指针类型,共 n 个元素,这是 “指针的数组”,即指针数组。
根据上面两个分析,可以看出,p 是什么,则词组的中心词就是什么,即数组 “指针” 和指针 “数组”。
———— 数组指针和指针数组_mick_hu 的博客 - CSDN 博客_数组指针和指针数组原文地址
3. c 语言优先级
C 语言运算符优先级(超详细)_embed_huang 的博客 - CSDN 博客_c 语言运算符优先级构成一系列表达式(六个左右),然后分析并打印输出他的结果原文地址