你还在恐惧指针吗?点进来,带你全方位深入了解指针

news/2023/6/7 23:19:50

指针是什么?在这里插入图片描述

指针也就是内存地址,指针变量是用来存放内存地址的变量。(存放在指针中的值都被当做地址处理)

对于32位的机器,假设有32根地址线,那么假设每根地址线在寻找地址的时候会产生高电平(高电压)和低电平(低电压)就是(1或者0)

那么32根地址线产生的地址就会是

00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000001
00000000 00000000 00000000 0000001011111111 11111111 11111111 11111111

这里就有2的32次方个地址

每个地址标识一个字节,那我们就可以给4G的空间进行编辑地址

2^32Byte == 2^32/1024KB ==2^32/1024/1024MB==2^32/1024/1024/1024GB == 4GB

在32位的机器上,地址是32个0或者1组成二进制序列,那地址就得用4个字节的空间来存储,所以
一个指针变量的大小就应该是4个字节

那么64根地址线产生的地址就会是

00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000010
...
11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111

这里就有2的64次方个地址

每个地址标识一个字节,那我们就可以给8G的空间进行编辑地址

2^64Byte == 2^64/1024KB ==2^64/1024/1024MB==2^64/1024/1024/1024GB == 8GB

在32位的机器上,地址是64个0或者1组成二进制序列,那地址就得用8个字节的空间来存储,所以
一个指针变量的大小就应该是8个字节

指针变量是用来存放地址的,地址是唯一标识一个内存单元的

指针的大小在32位平台是4个字节,在64位平台是8个字节

如何使用指针?

使用指针时会频繁进行以下几个操作:定义一个指针变量、把变量地址赋值给指针、访问指针变量中可用地址的值。这些是通过使用一元运算符 ***** 来返回位于操作数所指定地址的变量的值。

#include <stdio.h>int main ()
{int  var = 20;   /* 实际变量的声明 */int  *ip;        /* 指针变量的声明 */ip = &var;  /* 在指针变量中存储 var 的地址 */printf("var 变量的地址: %p\n", &var  );/* 在指针变量中存储的地址 */printf("ip 变量存储的地址: %p\n", ip );/* 使用指针访问值 */printf("*ip 变量的值: %d\n", *ip );return 0;
}

编译结果:

var 变量的地址: 0x7ffeeef168d8
ip 变量存储的地址: 0x7ffeeef168d8
*ip 变量的值: 20

C 中的 NULL 指针

在变量声明的时候,如果没有确切的地址可以赋值,为指针变量赋一个 NULL 值是一个良好的编程习惯。赋为 NULL 值的指针被称为指针。

NULL 指针是一个定义在标准库中的值为零的常量。

内存地址 0 有特别重要的意义,它表明该指针不指向一个可访问的内存位置。但按照惯例,如果指针包含空值(零值),则假定它不指向任何东西。

#include <stdio.h>int main ()
{int  *ptr = NULL;printf("ptr 的地址是 %p\n", ptr  );return 0;
}

编译结果:

ptr 的地址是 0x0

指针和指针类型

char *pc = NULL;   //char* 类型的指针是为了存放 char 类型变量的地址。
int *pi = NULL;    //int* 类型的指针是为了存放 int 类型变量的地址。
short *ps = NULL;  //short* 类型的指针是为了存放 short 类型变量的地址。
long *pl = NULL;   //long* 类型的指针是为了存放 long 类型变量的地址。
float *pf = NULL;  //float* 类型的指针是为了存放 float 类型变量的地址。
double *pd = NULL; //double* 类型的指针是为了存放 double 类型变量的地址。

指针±整数

#include <stdio.h>
//演示实例
int main()
{
int n = 10;
char *pc = (char*)&n;//因为n和pc类型不同,直接将pc指向n编译器会显示类型不兼容,如果一定要进行操作,需要对n进行强制类型转换
int *pi = &n;
printf("%p\n", &n);
printf("%p\n", pc);
printf("%p\n", pc+1);//因为char型占1个字节,所以向后移动1位
printf("%p\n", pi);
printf("%p\n", pi+1);//因为int型占4个字节,所以向后移动4位
return 0;
}

编译结果:

004FFB20
004FFB20
004FFB21
004FFB20
004FFB24

指针的类型决定了指针向前或者向后走一步是多大

指针的解引用

//演示实例
#include <stdio.h>
int main()
{
int n = 0x11223344;
char *pc = (char *)&n;
int *pi = &n;
*pc = 0; //重点在调试的过程中观察内存的变化。
*pi = 0; //重点在调试的过程中观察内存的变化。
return 0;
}

指针的类型决定了,对指针解引用的时候有多大的权限(能操作几个字节)。
比如: char* 的指针解引用就只能访问一个字节,而 int* 的指针的解引用就能访问四个字节

什么是野指针?

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

野指针产生的原因

  1. 指针未初始化
  2. 指针越界访问
  3. 指针指向的空间被释放

如何避免野指针的产生

  1. 指针初始化
  2. 小心指针越界
  3. 指针指向空间释放,及时置NULL
  4. 避免返回局部变量的地址
  5. 指针使用之前检查有效性

指针运算

指针±整数

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

指针-指针

int my_strlen(char *s)
{
char *p = s;
while(*p != '\0' )
p++;
return p-s;
}

指针的关系运算

for(vp = &values[N_VALUES]; vp > &values[0];)
{
*--vp = 0;
}

C语言标准规定

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

指针和数组

#include <stdio.h>
int main()
{
int arr[10] = {1,2,3,4,5,6,7,8,9,0};
printf("%p\n", arr);
printf("%p\n", &arr[0]);
return 0;
}

运行结果:

004FFDFC
004FFDFC

数组名表示的是数组首元素的地址

二级指针

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dtqh0XwL-1674044271602)(C:\Users\LENOVO\AppData\Roaming\Typora\typora-user-images\image-20230117222645294.png)]

a的地址存放在pa中,pa的地址存放在ppa中

pa是一级指针,ppa是二级指针

指针数组

int* arr[5];

arr是一个数组,有5个元素,每个元素是一个整形指针

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EHYYyA1K-1674044271604)(C:\Users\LENOVO\Desktop\arr.png)]

数组指针

数组指针的定义

数组指针是能够指向数组的指针,数组指针中存放的是数组的地址

int (*p)[10];//p先和*结合,说明p是一个指针变量,然后指着指向的是一个大小为10的整型的数组,所有p是一个指针,指向一个数组,叫数组指针

&数组名VS数组名的区别

&arr表示的是数组的地址,&arr+1表示跳过整个数组的大小

arr表示的是数组首元素的地址,arr+1表示跳过一个元素的大小

函数指针

函数指针是指向函数的指针变量。

通常我们说的指针变量是指向一个整型、字符型或数组等变量,而函数指针是指向函数。

函数指针可以像一般函数一样,用于调用函数、传递参数。

typedef int (*fun_ptr)(int,int); // 声明一个指向同样参数、返回值的函数指针类型

函数指针数组

数组是存放相同类型数据的存储空间,那要把函数的地址存到一个数组中,那这个数组就叫函数指针数组

指向函数指针数组的指针

指向函数指针数组的指针是一个指针

指针指向一个数组,数组的元素都是函数指针

定义形式

void (*(ppfunArr)[5])(const char*)=&pfunArr;//指向函数指针数组ppfunArr

回调函数

回调函数就是一个通过函数指针调用的函数,如果你把函数的指针(地址)作为参数传递给另一个函数当这个指针被用来调用其所指向的函数时,我们就说这是回调函数。回调函数不是由该函数的实现方法直接调用,而是在特定的事件或条件发生时由另外一方调用的,用于对该事件或条件进行响应

字符指针

方式1:

int main()
{
char ch = 'w';
char *pc = &ch;
printf("%c",*pc);
return 0;
}

方式2:

int main()
{
const char* pstr = "hello bit.";//本质是把字符串"hello bit"首字符的地址放到了pstr中
printf("%s\n", pstr);
return 0;
}

数当这个指针被用来调用其所指向的函数时,我们就说这是回调函数。回调函数不是由该函数的实现方法直接调用,而是在特定的事件或条件发生时由另外一方调用的,用于对该事件或条件进行响应

字符指针

方式1:

int main()
{
char ch = 'w';
char *pc = &ch;
printf("%c",*pc);
return 0;
}

方式2:

int main()
{
const char* pstr = "hello bit.";//本质是把字符串"hello bit"首字符的地址放到了pstr中
printf("%s\n", pstr);
return 0;
}

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

如若内容造成侵权/违法违规/事实不符,请联系郑州代理记账网进行投诉反馈,一经查实,立即删除!

相关文章

CentOS7.1下 安装vncserver和删除vnc占有的端口

今天给两台新服务器装CentOs7.1系统&#xff0c;然后装VNCServer的时候感觉网上的教程要么复杂多此一举&#xff0c;要么不清楚&#xff0c;关于-list端口的部分都没讲。所以这里整理一下&#xff0c;按着下面的顺序来就可以了。 1. 首先查看是否安装了VNCserver …

Android studio工具小技巧|文件日期|市场占有率|输出日志|adb安装apk

目录 1. Android studio项目目录树每个文件后出现时间日期显示 2. 新建项目时可以查看谷歌统计的关于Android各版本市场占有率 3. 命令行输出IDE的日志到电脑本地 4. 命令行安装apk到电脑usb连接的真机上 1. Android studio项目目录树每个文件后出现时间日期显示 在更新了…

ORACLE 删除归档日志连接rman查看归档日志占有率

我们都知道在controlfile中记录着每一个archivelog文件的相关信息&#xff0c;当然们在OS下把这些物理文件delete掉后&#xff0c;在我们的controlfile中仍然记录着这些archivelog文件的相关信息&#xff0c;在oracle的OEM管理器中有可视化的日志展现出&#xff0c;当我们手工清…

2018年JVM生态系统报告,2018年JAVA生态系统报告,2018年JAVA各种市场占有率

在Java开发者中&#xff0c;一直存在着很多鄙视链。如&#xff1a; IntelliJ → Eclipse → NetBeans Unix → Linux → Mac OS→ Windows → DOS Emacs → Vim → Sublime → Word → Power Point 这诸多鄙视链中一直存在着很大的争议 也正是存在诸多争议&#xff0c;导致…

Android各版本市场占有率

http://soft.yesky.com/mobile/422/84939422.shtml http://soft.yesky.com/mobile/422/84939422.shtml http://soft.yesky.com/mobile/422/84939422.shtml http://soft.yesky.com/mobile/422/84939422.shtml http://soft.yesky.com/mobile/422/84939422.shtml Android各版本…

java正规表达式之贪婪、非贪婪、占有量词

在甲骨文官网上介绍了量词及贪婪、非贪婪、占有量词之间的区别&#xff1a;https://docs.oracle.com/javase/tutorial/essential/regex/quant.html 使用到的测试程序 文章中在测试时使用了自定义的程序来测试正规表达式&#xff0c;在此&#xff0c;我将它改写成可以运行与ec…

Python绘制计算机CPU占有率变化的折线图

本篇文章将实现用Python获取系统信息CPU占有率并将其变化绘制成折线图。 第一步&#xff1a;获取系统CPU占有率信息 psutil模块是专门获取系统信息的模块&#xff0c;在该模块里有一个cpu_percent()方法是用来获取系统CPU占有率的。我们每隔1s获取一次CPU占有率&#xff0c;并…

想自己做个网站,常用的自助建站哪个好呢?需要注意什么

做网站图什么呢&#xff0c;大部分是人建站是想通过建站获取更多展现和流量&#xff0c;那么想要更多展现的话&#xff0c;我们更多的是去依靠搜索引擎&#xff0c;那么想要有好的排名&#xff0c;我们就要考虑到seo&#xff0c;很多人在建站初期根本不会去考虑seo的问题&#…