当前位置:首页 > 嵌入式培训 > 嵌入式学习 > 学习笔记 > 嵌入式学习笔记; c指针详解很详细,学霸总结

嵌入式学习笔记; c指针详解很详细,学霸总结 时间:2018-09-12      来源:未知

1.1 定义

在计算机内部存储器(简称内存)中,每一个字节单元,都有一个编号,称为地址。在C语言中,内存单元的地址称为指针,专门用来存放地址的变量,称为指针变量(pointer variable)。在不影响理解的情况下,把地址、指针、指针变量,都叫指针。

1.2 指针类型

1.2.1 构成

目标类型 *

-------- -

| |

| +----->数据为地址

+----------->任何类型

1.2.2 编码结构;无符号整数

1.2.3 长度:与机器位数有关

1.2.4 字面常量:NULL (void *)0 //表示指针变量中存的内容为0

注意: izeof(指针)一定是等于计算机的位数,与目标类型无关。

1.3 定义指针变量

1.31 定义指针变量的方法:

(1) 确定目标(变量)类型:char

(2) 确定指针类型:char *

(3) 定义指针变量:char *p;

实例:

实例:针对c[2][3]

1.3.2 认识指针变量

认识指针变量类型 ---> 认识目标类型

1.3.3 语法原理(注意观察)

变量 变量的指针类型 指向变量的指针变量定义

int a; int * int *pl

int a[3]; int (*)[3] int (*pr)[3];

char *a[3] char *(*)[3] char *(*p)[3];

1.4 取地址运算

语法:

&a(变量, 数组, 函数)

1.5 赋值运算

1.5.1 语法:p = a;

1.5.2 操作数类型:a和p类型相同

1.5.3 运算法则

(1) a的类型和p不相同时,编译器尝试自动转换:

a的类型转为p类型, 但p最好是void * 所有的编译器都行

(2) a--->p

1.5.4 结果:p的值,结果的类型是a的类型。

1.5.5 写运算的思路

(1) 确定运算符

(2) 确定操作数(类型)

1.5.6 看运算的思路:

(1) 确定操作数类型

(2) 确定运算法则

1.6 求目标

1.6.1 语法:*p

1.6.2 操作数类型:p必须为指针类型,但不能是void*。

1.6.3 法则:如果p = &a; 则 *p 就是a

1.6.4 结果:a

总结:px — 指针变量,它的内容是地址量。

*px — 指针所指向的对象,它的内容是数据。

&px — 指针变量占用的存储区域的地址,是个常量。

1.7 移动指向

1.7.1语法

p + n

p - n

p++, p--, ++p, --p

实例:

1.7.2操作数类型

p:p必须为指针,最好为非void*类型,gcc允许对void*的指针进行移动指向,但是其他编译器不一定可以

n:n必须为整数

1.7.3 运算法则

p + n

向地址增加方向移动n个目标, 即: p中的地址 + sizeof(目标类型也就是*p) * n

注意:sizeof(p)的大小一直为4.注意是sizeof(*p)

gcc允许p为void*,p + n表示将p中的地址加n

p - n

向地址减小方向移动n个目标, 即: p中的地址 - sizeof(目标类型) * n

p++

取p的值,作为结果,然后p = p + 1

++p

p = p + 1,然后取p的值,作为结果

p—

取p的值,作为结果,然后p = p - 1

--p

p = p – 1,然后取p的值,作为结果

注意:函数类型的指针不能做加减运算。

实例:

1.8 求指针之间的目标个数

1.8.1 语法

p1 - p2

1.8.2 操作数类型

p1和p2必须为相同类型的指针

如果p1和p2的类型都为void * 运算前都会被自动转换为long类型

1.8.3. 运算法则

(1) p1和p2类型为非void * 时

(p1中的地址 - p2中的地址) / sizeof(目标类型)

(2) p1和p2的类型为void *时(可能会有编译器不支持)

p1中的地址 - p2中的地址

1.8.4 结果

目标个数

实例:

1.9 关系运算

>, >=, <, <=, ==, !=

都可以用到指针类型数据, 但通常只用== 和 !=

1 语法

p1 == p2

2. 操作数类型

p1和p2类型相同

3. 运算法则

比较p1和p2中的地址

4. 结果

布尔值

注意:指针的[]运算

1.语法:p[n]

2.操作数类型:p 必须为指针或数组,n 必须为整数

3.运算法则:p[n] <==> *(p + n)

1.10指针常量

1.10.1定义:只读的指针变量

例子:

int a = 0;

int * const p1 = &a;(1)

const int *p2 = &a; (2)

int const *p3 = &a; (3)

const int * const p4 = &a; (4)

(1)中p1锁定,不能p++,或者p=p+1等操作

(2)中 int被锁定,a的值不能被修改,但p可以操作

(3)同(1)

(4)同(1)+(2)

注意:const int i;

int *const p = &i;//出现警告,因为是常量,但p认为,他的目标是可读可写,权限增加

1.11 数组 vs 指针

1.11.1 概念

指针数组: int * pa[5]; //实质是数组,数组的元素是指针

数组指针: int (*pa)[5]; //实质是指针,目标类型是个数组

数组的指针:数组的指针是指数组在内存中的起始地址,即第一个数组元素的地址。

1.11.2 一维数组 vs 指针

(1) 数组名, 在运算中(定义和声明除外都其他情况都是运算,但sizeof和&运算外), 可以被理解成指向第1个元素的指针(常量)

(2) a[n] 等价于 *(a + n)

(3) &a[n] 等价于 a + n

总结:数组类型和指针类型都可以做[]运算

指针变量和数组在访问数组中元素时,一定条件下其具有相同的形式,因为指针变量和数组名都是地址量。但指针变量和数组的指针(或叫数组名)在本质上不同,指针变量是地址变量,而数组的指针是地址常量

理解:由a[n]是一维数组可以得到:

(1) &a[n][0] 等价于 a[n]

即: a[n], 在运算中, 可以被理解成a[n][0]的指针

即: int *pl = a[n]; 语法正确

(2) a[n][m] 等价于 *(a[n] + m)

1.12字符指针与字符串

初始化字符指针是把内存中字符串的首地址赋予指针,并不是把该字符串复制到指针中。

注意:在C编程中,当一个字符指针指向一个字符串常量时,不能修改指针指向的对象的值。

补充:多级指针:指向指针的指针

上一篇:嵌入式学习笔记:c语言结构体定义和使用

下一篇:嵌入式学习笔记:二维数组定义与使用

热点文章推荐
华清学员就业榜单
高薪学员经验分享
热点新闻推荐
前台专线:010-82525158 企业培训洽谈专线:010-82525379 院校合作洽谈专线:010-82525379 Copyright © 2004-2022 北京华清远见科技集团有限公司 版权所有 ,京ICP备16055225号-5京公海网安备11010802025203号

回到顶部