当前位置: 首页 > article >正文

C语言之初阶指针

目录

  • 前言
  • 1. 什么是指针
    • 代码展示
  • 2. 计算机如何编址
  • 3. 指针类型
    • 指针类型的定义
    • 指针类型的意义
  • 4. 野指针
    • 4.1. **指针未初始化**
    • 4.2. **指针越界访问**
    • 4.3. **指针指向的空间被释放**
  • 5. 指针运算
  • 6. 指针和数组
  • 7. 二级指针
  • 8. 指针数组
  • 总结

前言

本篇将深入探讨C语言中至关重要的知识点——指针。鉴于指针内容的丰富性,我将其分为初阶和进阶两部分。初阶部分适合刚刚接触C语言的同学,许多人在学习指针时感到困惑,希望通过我的讲解,能让你们真正理解并掌握指针。现在,让我们立即开始这段指针之旅。

1. 什么是指针

在计算机科学中,指针(Pointer)是编程语言中的一个对象,它存储的是另一个变量的内存地址。通过这个地址,指针可以直接指向存储器中另一个地方的值。由于通过地址可以找到所需的变量单元,因此地址形象地被称为“指针”。换句话说,指针是通过它所存储的地址来找到对应的内存单元。

我们可以将指针类比为家的地址。如果想回家,就必须通过地址找到家的位置。指针就是存储地址的变量,通过指针可以访问对应的位置。

代码展示

#include <stdio.h>
int main()
{
    int a = 10; // 在内存中开辟一块空间
    int *p = &a; // 这里我们对变量a,取出它的地址,可以使用&操作符。
    // 将a的地址存放在p变量中,p就是一个指针变量。
    return 0;
}

总结:指针就是存储地址的变量。

2. 计算机如何编址

计算机如何为内存中的每个单元分配地址?一个单元的大小是多少?

经过仔细的计算和权衡,我们发现一个字节对应一个地址是最合适的。对于32位的机器,假设有32根地址线,每根地址线在寻址时产生一个电信号(正电/负电,即1或0),就会产生2的32次方个地址。

因此,在32位机器上,地址由32个比特位组成,用4个字节就能表示,所以一个指针占4个字节。对于64位机器,指针则占8个字节。

3. 指针类型

虽然指针的大小在32位机器上是4字节,在64位机器上是8字节,但指针并不是只有一种类型。为什么指针大小已经确定还要分整形指针、字符指针等数据类型呢?指针类型的意义又是什么呢?接下来我们用32位的机器来进行讲解。

指针类型的定义

int num = 10;
p = &num;

要将 &numnum 的地址)保存到 p 中,我们知道 p 就是一个指针变量,那它的类型是怎样的呢?我们给指针变量相应的类型。

char   *pc = NULL;
int    *pi = NULL;
short  *ps = NULL;
long   *pl = NULL;
float  *pf = NULL;
double *pd = NULL;

这里可以看到,指针的定义方式是:type + *。例如,char* 类型的指针是为了存放 char 类型变量的地址,int* 类型的指针是为了存放 int 类型变量的地址。

指针类型的意义

指针±整数

在这里插入图片描述

结果显示,int 类型的指针加1移动了4个字节,而 char 型指针移动了1个字节。

总结:指针类型决定了指针向前或向后走一步的大小。

指针的解引用

在这里插入图片描述
在这里插入图片描述

我们对比这两张图可以发现,char 类型的指针在访问变量 n 时只改变了一个字节的值,而 int 类型指针改变了 n 的4个字节。

总结:指针类型决定了对指针解引用的权限(能操作几个字节)。

4. 野指针

概念:野指针是指指针指向的位置是不可知的(随机的、不正确的、没有明确限制的)。指针变量在定义时如果未初始化,其值是随机的,指针变量的值是别的变量的地址,意味着指针指向了一个地址是不确定的变量,此时去解引用就是去访问了一个不确定的地址,所以结果是不可知的。

野指针成因

4.1. 指针未初始化

#include <stdio.h>
int main()
{ 
    int *p; // 局部变量指针未初始化,默认为随机值
    *p = 20;
    return 0;
}

4.2. 指针越界访问

#include <stdio.h>
int main()
{
    int arr[10] = {0};
    int *p = arr;
    int i = 0;
    for(i=0; i<=11; i++)
    {
        // 当指针指向的范围超出数组arr的范围时,p就是野指针
        *(p++) = i;
    }
    return 0;
}

4.3. 指针指向的空间被释放

在这里插入图片描述
这里a变量在text函数调用完就被释放了,指针pa得到了他的地址,但a的空间已经还给操作系统,所以pa就变成了野指针。

如何规避野指针

  1. 指针初始化
  2. 小心指针越界
  3. 指针指向空间释放后及时置 NULL
  4. 指针使用之前检查有效性

5. 指针运算

  1. 指针±整数
  2. 指针-指针
  3. 指针的关系运算

指针±整数

#define N_VALUES 5
float values[N_VALUES];
float *vp;
// 指针±整数;指针的关系运算
for (vp = &values[0]; vp < &values[N_VALUES];)
{
    *vp++ = 0;
}

在这里插入图片描述

解释:vp 指向了 values 数组的第一个元素,vp 小于 values 数组的最后一个元素后面的地址,vp就等于0,再加1。

指针-指针

指针-指针的运算,只能是指向同一块空间的指针才能计算。计算结果为指针之间元素的个数。

在这里插入图片描述

指针的关系运算

for (vp = &values[0]; vp < &values[N_VALUES];)
{
    *vp++ = 0;
}

标准规定:允许指向数组元素的指针与指向数组最后一个元素后面的那个内存位置的指针比较,但是不允许与指向第一个元素之前的那个内存位置的指针进行比较。

6. 指针和数组

指针和数组是两个不同的对象。

  • 指针是一个变量,用于存放地址的变量,大小为4或8个字节。
  • 数组是存放相同数据类型的集合,数组的大小由元素个数和元素类型决定。

数组名是数组首元素地址,地址可以放在指针变量里,通过指针来访问数组。

扩展:
在这里插入图片描述

7. 二级指针

指针变量也是变量,是变量就有地址,那指针变量的地址存放在哪里?这就是二级指针。

int a = 10;
int *pa = &a;
int **ppa = &pa;

在这里插入图片描述

也可以这样理解,pa 前的 * 是说 pa 是指针变量,指向的数据类型为 int,对于 ppa 来说,* 指的是 ppa 是指针变量,指向的数据类型是 int*

对于二级指针的运算有:

int b = 20;
*ppa = &b; // 等价于 pa = &b;
**ppa = 30; // 等价于 *pa = 30; 等价于 a = 30;

8. 指针数组

指针数组是指针还是数组?答案:是数组。是存放指针的数组。

int* arr[5]; // arr3是一个数组,有五个元素,每个元素是一个整形指针。

总结

指针是C语言中一个强大而灵活的工具,掌握指针的基本概念和用法对于理解C语言的内存管理和高级编程技巧至关重要。通过本文的介绍,你应该对指针的定义、声明、初始化、解引用、运算、与数组的关系、与函数的关系、空指针以及常见错误有了初步的了解。希望这些知识能够帮助你在C语言编程中更好地使用指针。


http://www.kler.cn/a/319305.html

相关文章:

  • 简单叙述 Spring Boot 启动过程
  • python 同时控制多部手机
  • Java面向对象编程进阶之包装类
  • MySQL技巧之跨服务器数据查询:进阶篇-从A数据库复制到B数据库的表中
  • uniapp+vue2 设置全局变量和全局方法 (兼容h5/微信小程序)
  • hadoop大数据平台
  • 【机器学习】自监督学习:解锁数据的无限潜能
  • 大数据-146 Apache Kudu 安装运行 Dockerfile 模拟集群 启动测试
  • ubuntu 安装minikube,并拉取k8s镜像
  • 2024年9月SCI-苔藓生长优化算法Moss Growth Optimization-附Matlab免费代码
  • 线性代数书中求解线性方程组的三种方法的实例
  • C标准库<string.h>-mem开头的函数
  • Linux安装Redis
  • 使用vite+react+ts+Ant Design开发后台管理项目(三)
  • 5G技术对IT行业的影响及未来发展
  • SpringBoot整合ELK实现日志监控(保姆级教程)
  • fo-dicom,第一个基于.NET Standard 2.0 开发的DICOM开源库
  • 【ANTLR】常见的几种编程语言表达模式
  • 古代经典名方目录数据库-支持经典名方检索!
  • IMS注册流程中的基本路由寻址过程
  • 西部移动硬盘怎么恢复数据?4种详细且实用的方法
  • 腾讯邮箱上传附件卡、慢、无法上传问题处理
  • 详解机器学习经典模型(原理及应用)——逻辑回归
  • neo4j小白入门
  • 记录踩坑 uniapp 引入百度地图(微信小程序,H5,APP)
  • 研一上课计划2024/9/23有感