深入理解指针1:指针变量、指针运算、野指针、const修饰指针

生活中我们把门牌号也叫地址,在计算机中我们把内存单元的编号也称为地址。C语⾔中给地址起
了新的名字叫:指针。
所以我们可以理解为:内存单元的编号==地址==指针

1、指针变量

我们知道的是:数组名是数组首元素的地址。也就是说,如果有一个arr数组,那么

arr == &arr[0];

两者都是常量,在程序的运行过程中,不会改变。但是,可以把它们赋值给指针变量,然后可以修改指针变量的值。

那如何创建指针变量呢?

int* p;

像这种就创建了一个指针变量p ,它的类型是int。指针变量也是一种变量,这种变量就是用来存放地址的,存放在指针变量的值都会被理解为地址。

#include <stdio.h>
int main()
{
    int a = 10;
    int* p = &a;
    
    return 0;
}

注意:存放什么类型的数据在指针变量的中,那么指针变量就是该类型。

int a = 10;
char* p = &a;

像这种,编译器就会产生从 int*到char*的类型不兼容的错误,我们应该避免掉。

指针变量的大小

32位机器假设有32根地址总线,每根地址线出来的电信号转换成数字信号后是1或者0,那我们把32根地址线产生的2进制序列当做一个地址,那么一个地址就是32个bit位,需要4个字节才能存储。
如果指针变量是用来存放地址的,那么指针变的大小就得是4个字节的空间才可以。
同理64位机器,假设有64根地址线,一个地址就是64个二进制位组成的二进制序列,存储起来就需要
8个字节的空间,指针变的大小就是8个字节。(x64环境下)

结论:

  • 32位平台下地址是32个bit位,指针变量大小是4个字节
  • 64位平台下地址是64个bit位,指针变量大小是8个字节
  • 注意指针变量的大小和类型是无关的,只要指针类型的变量,在相同的平台下,大小都是相同的。

指针的解引用 

用 * 符对指针进行解引用

指针的类型决定了,对指针解引用的时候有多大的权限(一次能操作几个字节)。

比如:char*类型的指针解引用就只能访问一个字节,而int*类型的指针解引用就能访问4个字节。

2、指针运算

指针+-整数

先来看一段代码,观察地址的变化

#include <stdio.h>
int main()
{
    int n = 10;
    char *pc = (char*)&n;
    int *pi = &n;
    printf("%p\n", &n);
    printf("%p\n", pc);
    printf("%p\n", pc+1);
    printf("%p\n", pi);
    printf("%p\n", pi+1);
    return 0;
}

代码的运行结果如下:

我们可以看出,char*类型的指针变量+1跳过1个字节, int*类型的指针变量+1跳过了4个字节。       指针的类型决定了指针向前或向后走一步有多大(距离)。

  • 指针的值是它所指向对象的地址。地址的表示方式依赖与计算机内部的硬件。许多计算机(包括PC和Macintosh)都是按字节编址,意思是内存中的每个字节都按顺序编号。这里,一个较大对象的地址(如double类型的变量)通常是该对象的第一个字节的地址。
  • 在指针前面使用 * 运算符可以得到该指针所指向对象的值。
  • 指针加1,指针的值递增它所指向类型的大小(以字节为单位)。
dates + 2 == &dates[2]     //相同的地址
*(dates + 2) == dates[2]  //相同的值

 取址

和所有变量一样,指针变量也有自己的地址和值。对于指针而言,&运算符给出指针本身的地址。

递增和递减指针

递增指向数组元素的指针可以让该指针移动至数组的下一个元素。因此,假设有一个指向数组的指针ptr,它的类型是int类型,ptr++相当于把ptr的值加上4,指向数组的下一个元素。

指针减去一个整数

指针必须是第一个运算对象,整数是第二个运算对象。该整数将乘以指针指向类型的大小(以字节为单位),然后用初始地址减去乘积。

从图可以看出 ptr - 2与&arr[2]等价。

指针求差

通常,求差的指针分别指向同一个数组的不同元素,通过计算求出两元素之间的距离。差值的单位与数组类型的单位相同。

2 的意思是这两个指针所指向的两个元素相隔两个int,而不是2字节。

const修饰指针

const修饰变量

变量是可以修改的,如果把变量的地址交给一个指针变量,通过指针变量也可以修改这个变量。但是如果我们希望一个变量加上一些限制,不能被修改,怎么做?这就是const的作用。

int main()
{
	int m = 0;
	m = 20; //m是可以修改的
	const int n = 0;
	n = 20; //n是不能被修改的
	return 0;
}

上述的n是不能被修改的,但是如果我们绕过n,使用n的地址,去修改n就能做到了,虽然这样做是在打破语法规则。

#include <stdio.h>
int main()
{
	const int n = 0;
	printf("n = %d\n", n);
	int* p = &n;
	*p = 20;
	printf("n = %d\n", n);
	return 0;
}

//结果
//n = 0
//n =20

const修饰指针变量

结论:const修饰指针变量的时候

  • const如果放在 * 的左边,修饰的是指针指向的内容,保证指针指向的内容不能通过指针来改变。但是指针变量本身的内容可变。
  • const如果放在 * 的右边,修饰的是指针变量本身,保证了指针变量的内容不能修改,但是指针指向的内容,可以通过指针改变。

野指针 

概念:野指针就是指针指向的位置是不可知的(随机的、不正确的、没有明确限制的)

成因

1、指针未初始化

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

2、指针越界访问

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

3、指针指向发空间释放

#include <stdio.h>
int* test()
{
    int n = 100;
    return &n;
}

int main()
{
    int*p = test();
    printf("%d\n", *p);
    return 0;
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

linux离线安装NodeJs

一、官方下载 地址&#xff1a;Node.js — Download Node.js 选择linux系统版本 为了防止安装过程出现一些适配问题&#xff0c;我没有选择下载最新版&#xff0c;实际应该下载你的前端所用的nodejs版本 未完待续。。

Object 类的使用

如何理解根父类 类 java.lang.Object是类层次结构的根类&#xff0c;即所有其它类的父类。每个类都使用 Object 作为超类。 Object类型的变量与除Object以外的任意引用数据类型的对象都存在多态引用 method(Object obj){…} //可以接收任何类作为其参数 Person o new Person(…

奇趣相机AI摄影,让每个儿童成长故事都独一无二

随着科技的日新月异&#xff0c;亲子互动方式也在不断进化。近日&#xff0c;一款名为“奇趣相机”的微信小程序凭借其精准捕捉亚洲儿童特质与激发创意的独特功能&#xff0c;在年轻父母群体中引发热烈关注。这款应用程序不仅革新了儿童摄影的传统模式&#xff0c;更成为连接科…

iOS App Store审核要求与Flutter应用的兼容性分析

本文探讨了使用Flutter开发的iOS应用能否上架&#xff0c;以及上架的具体流程。苹果提供了App Store作为正式上架渠道&#xff0c;同时也有TestFlight供开发者进行内测。合规并通过审核后&#xff0c;Flutter应用可以顺利上架。但上架过程可能存在一些挑战&#xff0c;因此可能…

Node.js-知识点学习总结归纳

Node.js-知识点学习总结归纳 安装nodenode运行方式通过Node.js直接运行js文件&#xff08;也就不用通过网页html了&#xff09;绝对路径调用:相对路径调用&#xff1a;直接运行js命令&#xff1a; Vscode控制台使用node运行js文件 安装node 这个就不用讲了吧&#xff0c;网上搜…

浅谈物联网高速公路智慧配电室系统构建方案

关键词&#xff1a;高速公路&#xff1b;智慧供配电&#xff1b;电力监控&#xff1b;配电室智能运维托管&#xff1b;安全隐患 0、引言 随着高速公路事业的不断发展和路网的不断延伸&#xff0c;传统的管理方式已难以满足日益增长的需求&#xff0c;动态管理和安全隐患预警成…

使用Python绘制发散条形图案例

发散条形图用于简化多个组的比较。它的设计允许我们比较各组中的数值。它还帮助我们快速地想象出有利的和不利的或积极的和消极的反应。条形图由从中间开始的两个水平条的组合组成-一个条从右向左延伸&#xff0c;另一个从左向右延伸。条形的长度与它所代表的数值相对应。 通常…

<网络> 网络Socket 编程基于UDP协议模拟简易网络通信

目录 前言&#xff1a; 一、预备知识 &#xff08;一&#xff09;IP地址 &#xff08;二&#xff09;端口号 &#xff08;三&#xff09;端口号与进程PID &#xff08;四&#xff09;传输层协议 &#xff08;五&#xff09;网络字节序 二、socket 套接字 &#xff08;…

【javaWeb 第十篇】(SpringBoot )yml配置文件

yml配置文件 配置文件参数配置化yml配置文件yml配置文件的基本语法yml数据格式 yml配置ConfigurationProperties 配置文件 参数配置化 为什么要使用配置文件配置参数&#xff1a; 以阿里云OSS工具类为例&#xff0c;在工具类中&#xff0c;需要给出连接阿里云服务器的种种参数…

delphi获取windows右下角任务栏图标信息

今天在群里,看有人问怎么获取windows右下角任务栏图标信息 win7 x64 测试通过 unit Unit1;interfaceusesWinapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,Vcl.Controls, Vcl.Forms, Vcl.Dialogs,commctrl, Vcl.StdCtr…

MVC模式和三层架构

一.概述 M:Model&#xff0c;业务模型&#xff0c;处理业务V&#xff1a;View&#xff0c;视图&#xff0c;界面展示C&#xff1a;Controller&#xff0c;控制器&#xff0c;处理请求&#xff0c;调用模型和视图 M即model模型是指模型表示业务规则。在MVC的三个部件中&#xf…

鸿蒙OS开发实例:【ArkTS类库异步并发简述Promise】

Promise和async/await提供异步并发能力&#xff0c;是标准的JS异步语法。异步代码会被挂起并在之后继续执行&#xff0c;同一时间只有一段代码执行&#xff0c;适用于单次I/O任务的场景开发&#xff0c;例如一次网络请求、一次文件读写等操作。异步语法是一种编程语言的特性&am…

云原生:为企业带来的7大价值

在数字化浪潮席卷全球的今天&#xff0c;企业正面临着前所未有的机遇与挑战。云原生技术&#xff0c;以其独特的优势&#xff0c;正逐渐成为企业实现数字化转型的重要"工具"。今天我们就来聊聊&#xff0c;云原生为企业带来的价值。 &#x1f525;提升敏捷性 云原生架…

怎么对电脑屏幕进行远程控制

远程控制是指管理人员在异地通过计算机网络异地拨号或双方都接入Internet等手段&#xff0c;连通需被控制的计算机&#xff0c;将被控计算机的桌面环境显示到自己的计算机上&#xff0c;通过本地计算机对远方计算机进行配置、软件安装程序、修改等工作。 远程控制并不仅仅局限…

Linux和Windows安装PHP依赖管理工具Composer

Composer 是 PHP 的一个依赖管理工具。它允许申明项目所依赖的代码库&#xff0c;会在项目中安装它们。 Composer 不是一个包管理器。是的&#xff0c;它涉及 "packages" 和 "libraries"&#xff0c;但它在每个项目的基础上进行管理&#xff0c;在你项目的…

一维卷积神经网络的特征可视化

随着以深度学习为代表的人工智能技术的不断发展&#xff0c;许多具有重要意义的深度学习模型和算法被开发出来&#xff0c;应用于计算机视觉、自然语言处理、语音处理、生物医疗、金融应用等众多行业领域。深度学习先进的数据挖掘、训练和分析能力来源于深度神经网络的海量模型…

基于ssm的三省学堂-学习辅助系统(java项目+文档+源码)

风定落花生&#xff0c;歌声逐流水&#xff0c;大家好我是风歌&#xff0c;混迹在java圈的辛苦码农。今天要和大家聊的是一款基于ssm的三省学堂-学习辅助系统。项目源码以及部署相关请联系风歌&#xff0c;文末附上联系信息 。 项目简介&#xff1a; 三省学堂-学习辅助系统的…

公司只有一个测试,要怎么继续呆下去?

在面试的时候&#xff0c;面试官可能会问&#xff1a;小公司、小团队&#xff0c;岗位就你一个人&#xff0c;怎么做 &#xff1f; 或者已经有的小伙伴已经在公司中面临只有一个测试的处境&#xff0c;这个时候我们应该怎么处理呢&#xff1f; 一 原因分析 公司只有一个测试人…

Golang 哈希表底层实现原理

1、本文讨论Golang的哈希表 Golang哈希表的实现&#xff0c;底层数据结构是数组单链表&#xff0c;链表节点由8个key、value和键的高八位组成的。为了方便理解&#xff0c;先简单看一个图快速理解。 我们来看一下Golang哈希表的结构体定义 简单介绍一下结构体中几个关键的…