6.指针-初阶

1.准备知识

1.1内存地址

  • 字节:字节是内存的容量单位,英文称为 byte,一个字节有8位,即 1byte = 8bits
  • 地址:系统为了便于区分每一个字节而对它们逐一进行的编号,称为内存地址,简称地址。

1.2基地址

  • 单字节数据:对于单字节数据而言,其地址就是其字节编号。
  • 多字节数据:对于多字节数据而言,期地址是其所有字节中编号最小的那个,称为基地址。

1.3取址符

  • 每个变量都是一块内存,都可以通过取址符 & 获取其地址
  • 例如:
int a = 100;
printf("整型变量 a 的地址是: %p\n", &a);

char c = 'x';
printf("字符变量 c 的地址是: %p\n", &c);

double f = 3.14;
printf("浮点变量 f 的地址是: %p\n", &f);
  • 注意:
    • 虽然不同的变量的尺寸是不同的,但是他们的地址的尺寸确实一样的。
    • 不同的地址虽然形式上看起来是一样的,但由于他们代表的内存尺寸和类型都不同,因此它们在逻辑上是严格区分的。

2.指针入门

2.1指针的概念

由于翻译的问题,以及口语表达的习惯,在日常表述中,指针在不同的场合会代表以下几个含义:

  • 指地址
    • 比如变量a的地址 &a,,这是一个地址当然也是一个指针
    • 我们可以说指针 &a 指向变量 a
  • 指指针变量
    • 比如 int *p; 此处变量p是指针变量,又常被简称指针

2.2指针的定义

int    *p1; // 用于存储 int  型数据的地址,p1 被称为 int  型指针,或称整型指针
char   *p2; // 用于存储 char 型数据的地址,p2 被称为 char 型指针,或称字符指针
double *p3; // 用于存储double型数据的地址,p3 被称为 double 型指针

2.3指针的赋值

赋给指针的地址,类型需跟指针的类型相匹配。

int a = 100;
p1 = &a; // 将一个整型地址,赋值给整型指针p1

char c = 'x';
p2 = &c; // 将一个字符地址,赋值给字符指针p2

double f = 3.14;
p3 = &f; // 将一个浮点地址,赋值给浮点指针p3

2.4指针的索引

所谓索引,指的是通过指针,取得其指向的目标

*p1 = 200; // 将 p1 指向的目标(即a)修改为200,等价于 a = 200;
*p2 = 'y'; // 将 p2 指向的目标(即c)修改为'y',等价于 c = 'y';
*p3 = 6.6; // 将 p3 指向的目标(即f)修改为6.6,等价于 f = 6.6;
  • 指针的尺寸
    • 指针尺寸指的是指针所占内存的字节数
    • 指针所占内存,取决于地址的长度,而地址的长度则取决于系统寻址范围,即字长
    • 结论:指针尺寸只跟系统的字长有关,跟具体的指针的类型无关

3.特殊指针

3.1野指针

  • 概念:指向一块未知区域的指针,被称为野指针。野指针是危险的。

  • 危害:

            a.引用野指针,相当于访问了非法的内存,常常会导致段错误(segmentation fault)

            b.引用野指针,可能会破坏系统的关键数据,导致系统崩溃等严重后果

  • 产生原因:

            a.指针定义之后,未初始化

            b.指针所指向的内存,被系统回收

            c.指针越界

  • 如何防止:

            a.指针定义时,及时初始化

            b.绝不引用已被系统回收的内存

            c.确认所申请的内存边界,谨防越界

        

3.2空指针

很多情况下,我们不可避免地会遇到野指针,比如刚定义的指针无法立即为其分配一块恰当的内存,又或者指针所指向的内存被释放了等等。一般的做法就是将这些危险的野指针指向一块确定的内存,比如零地址内存。

  • 概念:空指针即保存了零地址的指针,亦即指向零地址的指针。
  • 示例:
// 1,刚定义的指针,让其指向零地址以确保安全:
char *p1 = NULL;
int  *p2 = NULL;

// 2,被释放了内存的指针,让其指向零地址以确保安全:
char *p3 = malloc(100); // a. 让 p3 指向一块大小为100个字节的内存
free(p3);               // b. 释放这块内存,此时 p3 相当于指向了一块非法内存
p3 = NULL;              // c. 让 p3 指向零地址

4.指针运算

  • 指针加法意味着地址向上移动若干个目标
  • 指针减法意味着地址向下移动若干个目标
  • 示例:
int  a = 100;
int *p = &a; // 指针 p 指向整型变量 a

int *k1 = p + 2; // 向上移动 2 个目标(2个int型数据)
int *k2 = p - 3; // 向下移动 3 个目标(3个int型数据)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

玄月初二丶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值