0601-指针的基础

news2024/12/29 10:14:49

内存

物理存储器和存储地址空间

物理存储器:实际存在的具体存储器芯片。比如:内存条、RAM芯片、ROM芯片。
存储地址空间:对存储器编码的范围。

  • 编码:对每个物理存储单元(一个字节)分配一个号码
  • 寻址:可以根据分配的号码找到相应的存储单元,完成数据的读写

内存地址

  • 将内存抽象成一个很大的一维字符数组。
  • 编码就是对内存的每一个字节分配一个32位或64位的编号(与32位或者64位处理器相关)。
  • 这个内存编号我们称之为内存地址。
    内存中的每一个数据都会分配相应的地址:
  • char:占一个字节分配一个地址
  • int: 占四个字节分配四个地址
  • float、struct、函数、数组等

指针和指针变量

  • 指针就是地址,地址就是指针

    int a;
    int b[];
    int* p;
    

    上述代码中&a、和bp都是地址,也都是指针。

  • 指针变量是存放地址的变量

  • 通常我们叙述时会把指针变量简称为指针,实际他们含义并不一样

指针的基础知识

指针变量的定义和使用

定义指针的方式如下:
数据类型* 变量名
其中*表示该变量为指针变量,数据类型表示该指针变量保存的是哪一种数据类型的地址,也就是指针变量指向哪一种数据类型。

访问指针变量指向的内存空间的数据:
*指针变量
此处的*为取值运算符。
指针变量保存的是内存地址,*指针变量就表示访问该地址对应的内存空间。对*指针变量操作,其实就是读写该内存空间的数据。

#include<stdio.h>

int main() {

	int a = 10;
	int* p;

	p = &a;

	printf("a = %d\n", a);
	printf("p指向的数据=%d\n", *p);
	printf("变量a的地址:%p\n", &a);
	printf("指针变量p存的地址:%p\n", p);

	return 0;
}

运行上面代码,结果如下:
在这里插入图片描述
注意:&可以取得一个变量在内存中的地址。但是,不能取寄存器变量,因为寄存器变量不在内存里,而在CPU里面,所以是没有地址的。

使用指针访问数据的原理
不同类型的数据在内存中占用不同的字节数,指针变量保存的是数据首个字节的地址。系统根据指针变量保存的地址找到首个字节后,再根据指针指向的数据类型,顺位读取不同的字节长度,从而访问到完整的数据。

比如,一个int型变量a占4字节,指针变量int* p只保存了a在内存中的首个字节的地址。当操作*p时,系统会先根据该地址找到首个字节,然后再顺位读取3个字节,总共读取了4个字节,从而取出变量a的值。

通过指针间接修改变量的值

#include<stdio.h>

int main() {

	int a = 10;
	int* p;

	p = &a;

	printf("a = %d\n", a);
	printf("p指向的数据=%d\n", *p);
	printf("变量a的地址:%p\n", &a);
	printf("指针变量p存的地址:%p\n", p);

	*p = *p + 1;
	printf("p指向的数据加1后,a = %d\n", a);
	printf("p指向的数据加1后,p指向的数据=%d\n", *p);

	return 0;
}

运行上面的代码,结果如下:
在这里插入图片描述
在定义指针类型时一定要和指向的变量类型是一样的才行。

#include<stdio.h>

int main() {
	char a = 97;
	int* p = &a;

	printf("a的值=%d\n", a);
	printf("*p的值=%d\n", *p);
	return 0;
}

运行上面的代码,结果如下:

在这里插入图片描述
上面代码中,虽然指针变量p保存的是字符变量a的地址,但是p是指向int型数据的,所以在找到a的地址后还会顺位读取3个字节的数据。
在这里插入图片描述

指针大小

windows中数据存储采用小端对齐的方式。也就是,数据的低位放在地址小的内存中。
在这里插入图片描述
指针也是一种数据类型,所以可以使用sizeof()测量指针的大小,得到的总是:4或8。
这是因为指针存储的是内存地址。在32位处理器中内存地址是一个32位的编号,在64位处理器中内存地址是一个64位的编号。
所以在32位处理器中sizeof(指针)得到的总是4,在64位处理器中sizeof(指针)得到的总是8。

在visio studio中可以在下图中选择基于32位或64位的处理器编译,从而使sizeof(指针)得到不同的结果。
在这里插入图片描述

int main() {
	int* p1;
	int** p2;
	char* p3;
	char** p4;
	printf("sizeof(p1) = %d\n", sizeof(p1));
	printf("sizeof(p2) = %d\n", sizeof(p2));
	printf("sizeof(p3) = %d\n", sizeof(p3));
	printf("sizeof(p4) = %d\n", sizeof(p4));
	printf("sizeof(double *) = %d\n", sizeof(double*));

	return 0;
}

上述代码基于32位处理器编译运行后结果如下:
在这里插入图片描述
上述代码基于64位处理器编译运行后结果如下:
在这里插入图片描述

野指针和空指针

野指针

任意数值赋值给指针变量没有意义,因为这样的指针就成了野指针,此指针指向的区域是未知(操作系统可能不允许操作此指针指向的内存区域)。所以,野指针不会直接引发错误,操作野指针指向的内存区域可能会出问题。

int main() {
	int* p = 100;
	/*
	 操作系统将0~255的内存空间作为系统占用,
	 不允许被访问操作
	*/
	printf("%d\n", *p);
	return 0;
}

空指针

为了标志此指针变量没有指向任何变量(空闲可用),C语言中,可以把NULL赋值给此指针,这样就标志此指针为空指针。

int *p = NULL;

NULL是一个值为0的宏常量:

#define NULL    ((void *)0)

空指针可用于条件判断

	int* p = NULL;
	if (p == NULL) {
		printf("我是一个空指针\n");
	}
	else {
		printf("我不是一个空指针\n");
	}

万能指针void *

万能指针可以接收任意数据类型的地址。但不能直接访问万能指针指向的内存空间,因为系统找到数据的首个字节后,不知道接下来要顺位读取多少个字节。

必须先将万能指针强转为某个具体类型的指针变量后才可以访问。

#include<stdio.h>

int main() {
	int a = 10;
	void* p = &a;
	printf("变量a的值:%d\n", a);
	//printf("万能指针p指向的值:%d\n", *p);//不能直接访问万能指针指向的内存空间
	printf("万能指针p指向的值:%d\n", *(int*)p);

	*(int*)p = *(int*)p + 1;
	printf("加1后,变量a的值:%d\n", a);
	printf("加1后,万能指针p指向的值:%d\n", *(int*)p);
	return 0;
}

执行上面代码,结果如下:
在这里插入图片描述

const修饰的指针变量

const 数据类型* 变量名const修饰数据类型,说明该指针变量指向的内存空间可读不可写。

数据类型* const 变量名const修饰变量名,说明该指针变量保存的内存地址可读不可写。

const 数据类型* const 变量名const既修饰数据类型又修饰变量名,说明该指针变量指向的内存空间可读不可写,保存的内存地址也是可读不可写的。

#include<stdio.h>

int main() {
	const int a = 10;
	//a = 20;//err
	int b = 20;

	const int* p = &a;
	printf("指针变量p指向的值:%d\n",*p);
	//*p = 30;//err
	p = &b;//ok
	printf("指针变量p指向的值:%d\n", *p);

	int* const p2 = &a;
	printf("指针变量p2指向的值:%d\n", *p2);
	//p2 = &b;//err
	*p2 = 30;//ok
	printf("指针变量p2指向的值:%d\n", *p2);
	printf("a的值:%d\n", a);


	const int* const p3 = &b;
	//*p3 = 40;//err
	//p3 = &a;//err
	printf("指针变量p3指向的值:%d\n", *p3);
	b = 40;
	printf("指针变量p3指向的值:%d\n", *p3);
	return 0;
}

运行上面代码,结果如下:
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/544651.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

520网络情人节:用双语告白你的女神男神!

网络情人节&#xff08;Network Valentines Day&#xff09;——520、521被喻为“我愿意、我爱你” 的意思&#xff0c;又被称为“结婚吉日”、“表白日”、“撒娇日”、“求爱节”。每年5月20日和5月21日的“网络情人节”也成为了情侣们扎堆登记结婚、隆重举办婚宴 的吉日。 5…

系统分析师经典易错题,解题思路一

数据库通常采用三级模式结构,其中,视图对应外模式,基本表对应模式,存储文件对应内模式。数据的独立性是由DBMS的二级映像功能来保证的。数据的独立性包括数据的物理独立性和数据逻辑独立性。数据的物理独立性是指当数据库的内模式发生改变时,数据的逻辑结构不变。为了保证…

HTML获取SpringBoot从model传的值

controller层如下&#xff1a; html获取格式&#xff1a;[[${传入的值}]] 效果图&#xff1a;

Mybatis操作数据库执行流程的先后顺序是怎样的?

MyBatis是一个支持普通SQL查询、存储及高级映射的持久层框架&#xff0c;它几乎消除了JDBC的冗余代码。使Java开发人员可以使用面向对象的编程思想来操作数据库。对于MyBatis的工作原理和操作流程的理解&#xff0c;我们先来看下面的工作流程图。 MaBatis的工作流程 在上图中…

VMware和Ubuntu20.04的安装

VMware安装&#xff1a; 1、下载好VM后右击管理员运行&#xff1a; PS&#xff1a;推荐大家去官网下载&#xff0c;如果需要许可密钥的话&#xff0c;可以去搜一下&#xff0c;或者私信一下UP&#xff0c;链接放下面了。 VM官网 因为我已经安装好了&#xff0c;所以就不在贴…

Appium自动化环境搭建保姆级教程

APP自动化测试运行环境比较复杂&#xff0c;稍微不注意安装就会失败。我见过不少朋友&#xff0c;装了1个星期&#xff0c;Appium 的运行环境还没有搭好的。 搭建环境本身不是一个有难度的工作&#xff0c;但是 Appium 安装过程中确实存在不少隐藏的比较深的坑&#xff0c;如果…

5.1图的物理结构与基本操作

1.图的物理结构 一.邻接矩阵存储稠密图 用于存储无向图&#xff0c;有向图&#xff0c;总之各类图 优缺点&#xff1a;适合存储稠密图&#xff0c;属于上下三角矩阵&#xff0c;有重复 复杂度&#xff1a;O(V),空间O(V^2) 性质&#xff1a;阶乘得到某一点的值&#xff0c;为顶…

C语言入门级小游戏——三子棋

文章目录 游戏文件的创建游戏菜单重头戏&#xff0c;游戏正式开始棋盘的创建数据清空打印棋盘 玩家下棋电脑下棋输赢的判断1.赢2.平局&#xff0c;游戏继续 代码展示 今天我们写一个小游戏——三子棋来增加我们对编程的兴趣&#xff0c; 希望这篇文章对友友们有帮助! 游戏文件的…

测试进阶-软件测试的分类

目录 按照测试对象划分界面测试 *可靠性测试如何进行可靠性测试 容错性测试文档测试兼容性测试 *易用性测试 *安装卸载测试 *安全测试性能测试内存泄漏测试 按照是否查看代码划分黑盒测试白盒测试灰盒测试 按照开发阶段划分测试金字塔单元测试集成测试系统测试回归测试冒烟测试…

行政前台快递管理软件使用教程

行政前台快递如何管理&#xff0c;是每个行政人员永远避不开的话题。 不管是从行政相关的论坛中&#xff0c;还是从身边从事行政相关工作的亲友口中&#xff0c;亦或是某些公司前台堆积的快递&#xff0c;我们都能看到、听到行政相关人员抱怨“行政前台快递管理为什么这么难”…

办公环境监测与智能控制软硬件全套解决方案

心理学研究表明&#xff0c;良好的工作环境对员工的身心健康及提高工作效率有积极影响。 不仅如此&#xff0c;近几年国家尤其提倡“碳中和”与“碳达峰”政策&#xff0c;并提出“节约能源、美化环境”的重要目标。以“企业数字化转型”为根本&#xff0c;一切事物都在朝着智能…

因子图优化

最大后验概率估计问题 我们常将状态估计问题建模为最大后验估计&#xff08;MAP&#xff09;。之所以命名为最大后验估计&#xff0c;是因为它在给定了观测 Z \bm Z Z的情况下&#xff0c;最大化状态 X \bm X X的后验概率密度 p ( X ∣ Z ) p(\bm X|\bm Z) p(X∣Z) X M A P …

迅为RK3568开发板驱动教程更新了兄弟们,思路更科学

驱动视频全新升级&#xff0c;并持续更新~更全&#xff0c;思路更科学&#xff0c;入门更简单。 迅为基于iTOP-RK3568开发板进行讲解&#xff0c;本次更新内容为第九期&#xff0c;主要讲解设备模型&#xff0c;共计29讲。 教程观看链接&#xff1a;B站搜索-迅为电子 课程目录…

Mysql——SUM()函数

目录 一、前期准备工作 新建表如下&#xff1a; 插入的数据如下&#xff1a; 二、SUM()函数的用法 1.求和&#xff0c;返回指定列的总和 SUM 函数可以对单个列求和&#xff0c;也可以对多个列运算后求和&#xff0c;计算中忽略 NULL 值 SUM函数与分组 GROUP BY 使用&a…

MySQL调优系列(五)——索引详解

一、索引的定义 数据库索引就像是书前面的目录&#xff0c;能加快数据库的查询速度。 索引是一种数据结构&#xff0c;用于帮助我们在大量数据中快速定位到我们想要查找的数据。 是一种帮助MySQL高效获取数据的数据结构。 ps&#xff1a;大多数情况下&#xff0c;索引查询都是…

计算机图形学 | 实验九:纹理贴图和天空盒

计算机图形学 | 实验九&#xff1a;纹理贴图和天空盒 计算机图形学 | 实验九&#xff1a;纹理贴图和天空盒实验概述顶点数据立方体顶点数据天空盒顶点数组 纹理载入创建纹理纹理读取纹理绑定 使用纹理立方体着色器顶点着色器片元着色器 天空盒着色器顶点着色器片元着色器 立方体…

管好【SD-WEBUI】中大量的模型:模型信息预览插件(Part.3)

文章目录 &#xff08;零&#xff09;前言&#xff08;一&#xff09;模型预览图&#xff08;一&#xff09;模型信息预览插件&#xff08;Model Preview&#xff09;&#xff08;1.1&#xff09;示例&#xff08;Markdown描述提示词备注&#xff09;&#xff08;1.2&#xff0…

AI大模型驱动下,数字虚拟人与虚拟场景为高等学院建设带来何种改变?

继今年年初美国人工智能研究实验室OpenAI推出ChatGPT&#xff08;一种人工智能驱动的自然语言处理工具&#xff09;之后一段时间里&#xff0c;阿里、百度、商汤等一众国内IT巨头纷纷发布了各自的AI大模型&#xff08;可浅理解为用于AI学习用的超大量数据&#xff09;&#xff…

运动控制轴单位设置(H5U PLC)

H5U PLC运动控制相关应用,请参看下面博客文章 10轴总线控制(汇川H5UPLC+总线伺服编程应用)_RXXW_Dor的博客-CSDN博客H5UPLC控制总线伺服的详细配置过程,可以参看下面的文章链接:汇川H5U PLC通过EtherCAT总线控制SV660N和X3E伺服_ethercat总线伺服如何控制_RXXW_Dor的博客-C…

使用MFT进行加密文件传输的7个好处

至少&#xff0c;托管文件传输&#xff08;MFT&#xff09;解决方案是一种产品&#xff0c;它包含入站和出站文件传输的所有方面&#xff0c;同时使用行业标准的网络协议和无缝加密。它可以从单个集中管理点在您的网络&#xff0c;系统&#xff0c;应用程序&#xff0c;贸易伙伴…