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

C 指针初识

这是一个变量的声明及初始化语句:int a=10;在程序员眼中,会关注:变量a的类型和变量a的值;而在系统计算机眼中,可能是这样的:在地址0x1234开始占用了四个字节的内存,这个内存上需要写入一个整型值10;
对,我们在初学c程序时,会先学习使用变量的别名a,来操作变量--这种方式被称为直接访问变量;而c程序给予程序员一种间接访问变量的能力,即:通过内存地址访问。

如何获取变量地址

在上面我们了解到,在计算机眼中,变量需要根据其类型开辟一块内存空间,供程序员读写。也提到c程序给予程序员获取变量的内存地址、并使用地址简介实现如同变量的操作。这里我们先介绍,如何获取变量的地址,它便是“&”--取地址操作符。

#include <stdio.h>int main(void) {int a = 10;printf("变量a被存储到内存中的位置是:%p\n", &a);return 0;
}

输出

变量a被存储到内存中的位置是:0x16dc83538

int类型数据在内存中占用了4字节,使用&符号获取到的是这一段(四个字节)内存的地址起点。--初学者很容易将&符号取到的地址认为变量就存在这个地址处,下一个字节的地址就不属于这个变量了;在本例中往后再数四个字节才不再是本变量的地址范围。

新的数据类型--指针类型

由于地址类型的特殊性,c程序提供了一种特殊的数据类型来表示它,即:指针类型,它的形式是:数据类型 * 变量名;

#include <stdio.h>int main(void) {int a = 10;int *ptr = &a;printf("变量a被存储到内存中的位置是:%p\n", ptr);return 0;
}

输出:

变量a被存储到内存中的位置是:0x16da43538

看到指针类型变量我们要有以下认知:

  • 指针类型变量存储的值是内存地址,内存地址在计算机中通常以16进制整型数表示,但不能把整型数和指针类型画等号;
  • 指针存储的地址处存储的值类型--即指针指向的类型,这一点很重要,解引用时若不知道指针指向变量的类型,计算机就不知道如何解引用了;比如解引用时往后取多少个字节合适?long和double都占用8个字节,但在计算机中的存储形式差别很大,若不知道指针指向的内存处值的类型,又该如何处理?。

间接操作符*--解引用

获取到变量地址后,若何通过指针变量操作,对应地址处的数据?答案是:通过*指针变量的方式,可如同普通变量一样,操作该地址处的内存。

#include <stdio.h>int main(void) {int a = 10;int *ptr = &a;*ptr = 11;printf("变量a现在的值为%d\n", a);return 0;
}

输出:

变量a现在的值为11

此后我们既可以用普通变量名直接操作变量、也可以通过*指针变量名操作变量了。

指针作为函数形参

此前我们知道,函数对形参的修改并不会影响实参,但就如下面的函数:实现两个数的交换。我们的目的就是要a、b两个实参的数据交换。

#include <stdio.h>void exchange(int x, int y);int main(void) {int a = 10;int b = 20;printf("交换前,a:%d,b:%d\n", a, b);exchange(a, b);printf("交换后,a:%d,b:%d\n", a, b);return 0;
}void exchange(int x, int y) {printf("交换前,x:%d,y:%d\n", x, y);int tmp = x;x = y;y = tmp;printf("交换后,x:%d,y:%d\n", x, y);
}

输出:

交换前,a:10,b:20
交换前,x:10,y:20
交换后,x:20,y:10
交换后,a:10,b:20

在函数内部,形参x、y确实实现了交换;但是在main函数中 a、b的值却未发生交换;之前我们在讲函数形参和实参的关系时讲过,现在我们从地址的角度上再看下为什么对x、y的修改,无法影响 a、b;
image
从上图可以看到,x,y的地址和a、b都不一样,就是说这四个变量已经毫不相干。所以对x、y的修改影响不了a、b。
在了解指针前,我们很难将交换后的x,y的值传递出来;
但在解到指针能够通过地址实现操作内存的能力后,我们可以将形参改成地址类型,在函数内部直接操作该地址处的内存,达到对函数体外变量数据的修改。

#include <stdio.h>void exchange(int* x, int* y);int main(void) {int a = 10;int b = 20;printf("交换前,a:%d,b:%d\n", a, b);exchange(&a, &b);printf("交换后,a:%d,b:%d\n", a, b);return 0;
}void exchange(int* x, int* y) {// printf("交换前,x:%d,y:%d\n", *x, *y);int tmp = *x;*x = *y;*y = tmp;// printf("交换后,x:%d,y:%d\n", *x, *y);
}

输出

交换前,a:10,b:20
交换后,a:20,b:10

总结:有了指针之后,我们拥有了直接操作内存的能力;指针的出现,还带来了“节约内存”、“实现普通变量实现不了的能力”等等,指针还有更多细节等着我们去发现。

http://www.jsqmd.com/news/35817/

相关文章:

  • 翻译[9]-让sshfs再次伟大于浏览器中
  • 计算机毕业设计-基于Java的口腔管理平台系统创建实战(附源码+论文+演示视频)
  • 唯识主义:哲学爱智慧本质的当代回归 - 实践
  • 第一届湖南省信息学拔尖创新挑战活动 总结
  • U629961 焦头烂额的日奈委员长 の markdown
  • Java数组——Array类讲解
  • 论文笔记(九十三)ManipulationNet: Benchmarking - 实践
  • flask: 用flask-wtf校验参数
  • hdh
  • 序列密码的线性滤波模型
  • 使用Milvus和DeepSeek构建RAG demo - 实践
  • python里字面量是什么?
  • 圆锥滚子轴承品牌:行业顶尖选择与专业解析
  • 串串重学
  • 如何写毕业论文?10个高效写作技巧+AI论文工具推荐(2025最新)
  • avro 数据入门
  • 2025龙信杯个人Wp
  • 7大AI论文写作工具必备!论文写作辅助神器推荐!
  • flask: 报错:The CSRF token is missing.
  • Java数组——二维及多维数组
  • 详细介绍:MySql复习及面试题学习
  • MATLAB 实现 SRCNN 图像超分辨率重建
  • 2025.11.03~2025.11.09
  • 2025年热门的安全检测检验公司综合排名
  • 详细介绍:Python 2025年10月最新:多平台域名/小程序封禁检测工具
  • 多快省力插件使用帮助说明
  • 人工势场法(APF)路径规划 MATLAB
  • MySQL--多表查询
  • ABC431 解题报告
  • 哈佛放屁都是香的?