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

你是真的“C”——详解指针知识

你是真的“C”——详解指针知识😎

  • 前言🙌
  • 1、 指针是什么?🙌
  • 2、指针和指针类型🙌
    • 2 、1指针+-整数
    • 2 、 2指针的解引用
  • 3、 野指针🙌
    • 3、 1野指针成因
    • 3、 2如何规避野指针
    • 4、指针运算🙌
    • 4、1 指针+-整数
    • 4、2 指针-指针
    • 4、3 指针的关系运算
  • 5、指针和数组🙌
  • 6 、 二级指针🙌
  • 7、指针数组🙌
  • 总结撒花💞

追梦之旅,你我同行

   
😎博客昵称:博客小梦
😊最喜欢的座右铭:全神贯注的上吧!!!
😊作者简介:一名热爱C/C++,算法等技术、喜爱运动、热爱K歌、敢于追梦的小博主!

😘博主小留言:哈喽!😄各位CSDN的uu们,我是你的博客好友小梦,希望我的文章可以给您带来一定的帮助,话不多说,文章推上!欢迎大家在评论区唠嗑指正,觉得好的话别忘了一键三连哦!😘
在这里插入图片描述

前言🙌

    哈喽各位友友们😊,我今天又学到了很多有趣的知识现在迫不及待的想和大家分享一下!😘我仅已此文,和大家分享C语言中指针相关的知识点~ 都是精华内容,可不要错过哟!!!😍😍😍

1、 指针是什么?🙌

在学习指针之前,首先要知道指针是什么?,其实,指针理解起来可以概括为一下两个要点:

  1. 指针是内存中一个最小单元的编号,也就是地址
  2. 平时口语中说的指针,通常指的是指针变量,是用来存放内存地址的变量
    总结:指针就是地址,口语中说的指针通常指的是指针变量。
  3. 指针变量:我们可以通过&(取地址操作符)取出变量的内存起始地址,把地址可以存放到一个变量中,这个变量就是指针变量

举个栗子辅助理解:

#include <stdio.h>
int main()
{int a = 10;//在内存中开辟一块空间int* p = &a;return 0;}

知识点分析:

  • 这里我们对变量a,取出它的地址,可以使用&操作符。
  • a变量占用4个字节的空间,这里是将a的4个字节的第一个字节的地址存放在p变量
  • 中,p就是一个之指针变量。

小结一下:
指针变量,用来存放地址的变量。(存放在指针中的值都被当成地址处理)。

   那么,一个内存单元要分配多大的空间呢?又是怎么对这些内存进行编地址的呢?无数的先辈对此进行探讨分析,最终认为一个内存单位分配一个字节,并分配一个地址是比较合适的。对于32位的机器,,假设有32根地址线,那么假设每根地址线在寻址的时候产生高电平(高电压)和低电平(低电压)就是(1或者0)。那么这里就有2的32次方个地址。同样的方法,那64位机器,如果给64根地址线,那能编址就有2的64次方的地址。
简单的概括来说
在32位的机器上,地址是32个0或者1组成二进制序列,那地址就得用4个字节的空间来存储,所以
一个指针变量的大小就应该是4个字节。
那如果在64位机器上,如果有64个地址线,那一个指针变量的大小是8个字节,才能存放一个地
址。
总结:

  • 指针变量是用来存放地址的,地址是唯一标示一个内存单元的
  • 指针的大小在32位平台是4个字节,在64位平台是8个字节

2、指针和指针类型🙌

我们都知道,变量有不同的类型,整形,浮点型等。那指针有没有类型呢?准确的说是有的。指针的定义方式是: type + * 。
举些栗子大家就知道啦:

char* 类型的指针是为了存放 char 类型变量的地址。
short* 类型的指针是为了存放 short 类型变量的地址。
int* 类型的指针是为了存放 int 类型变量的地址。

那指针类型的意义是什么?

2 、1指针±整数

这里通过画图的方式帮助大家辅助理解正指针加减运算的规律:
在这里插入图片描述总结指针的类型决定了指针向前或者向后走一步有多大(距离)

2 、 2指针的解引用

那么指针的解引用和指针的类型有没有什么关联呢?这里还是通过画图的方法帮助大家理解:

在这里插入图片描述
在这里插入图片描述
总结:
指针的类型决定了,对指针解引用的时候有多大的权限(能操作几个字节)
比如: char* 的指针解引用就只能访问一个字节,而 int* 的指针的解引用就能访问四个字节。

3、 野指针🙌

按照教科书上的解释概念: 野指针就是指针指向的位置是不可知的(随机的、不正确的、没有明确限制的)。按照我的理解,野指针其实就像是一条没有被绳子拴住的野狗,到处乱串,当使用它时(解引用),就会有危险。

3、 1野指针成因

对于野指针存在的原因分析,比较常见的可以归纳为以下几个:

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

指针未初始化导致野指针,这里举个栗子分析以下:

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

在这里插入图片描述

小结:局部变量指针未初始化,默认为随机值

指针越界访问造成野指针,这里举一个简单的栗子:


#include <stdio.h>
int main()
{int arr[10] = {0};int *p = arr;int i = 0;for(i=0; i<=11; i++){*(p++) = i;}return 0;
}

小结一下:
这个数组一共只有10个元素,循环却访问到了第11个元素的位置。 当指针指向的范围超出数组arr的范围时,p就是野指针。
指针指向的空间释放,当再次访问原空间时,造成野指针。

int * test()
{int a = 10;return &a;
}int main()
{int* p = test();printf("%d", *p);return 0;
}

小结一下:
变量a是test内的局部变量,当运行的时候出了这个函数时,就会被销毁掉,这里却返回a变量的地址赋值给指针p,p去解引用操作不属于程序的空间,则造成了野指针的问题。

3、 2如何规避野指针

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

4、指针运算🙌

4、1 指针±整数

上面已经探讨了这个知识点,这里就不做讲解了。

4、2 指针-指针

这里举一个模拟实现strlen函数的代码:

#include<stdio.h>
#include<assert.h>
int my_strlen(const char* p)
{assert(p);char* str = p;while (*p != '\0'){p++;}return p - str;
}int main()
{char arr[] = "Hello bit!";printf("%d", my_strlen(arr));return 0;
}

在这里插入图片描述

这里的返回值就是指针 - 指针的典型体现啦。指针减去指针,得到的是两个指针之间元素的个数

4、3 指针的关系运算

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

5、指针和数组🙌

指针和数组是不是同一个东西?其实不是的。虽然我们常说数组名是首元素的地址,好像和指针有紧密的关系,但指针和数组是完全不一样的两个东西。

在这里插入图片描述

在这里插入图片描述可见数组名和数组首元素的地址是一样的。
结论:数组名表示的是数组首元素的地址

既然可以把数组名当成地址存放到一个指针中,我们使用指针来访问一个数组中的元素就成为可能。所以 p+i 其实计算的是数组 arr 下标为i的地址。
那我们就可以直接通过指针来访问数组,举个栗子:

#include <stdio.h>
int main()
{int arr[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };int* p = arr; int sz = sizeof(arr) / sizeof(arr[0]);int i = 0;for (i = 0; i < sz; i++){printf("%d ", *(p + i));}return 0;
}

在这里插入图片描述

6 、 二级指针🙌

指针变量也是变量,是变量就有地址,那指针变量的地址存放在哪里?其实,还是存放到指针变量中。

这里举个栗子辅助大家理解一下:

#include <stdio.h>
int main()
{int a = 10;//a是要在内存中申请4个字节的空间的//一级指针int* pa = &a;// pa是指针变量,用来存放地址,也得向内存申请,申请4/8,存放变量a的地址//二级指针int** ppa = &pa;//ppa是指针变量,用来存放地址,也得向内存申请,申请4/8,存放一级指针地址int** * pppa = &ppa;//pppa是指针变量,用来存放地址,也得向内存申请,申请4/8,存放二级指针地址printf("%d\n", **ppa);return 0;
}

如图所示:
在这里插入图片描述
对于二级指针的运算有:

  • *ppa 通过对ppa中的地址进行解引用,这样找到的是 pa , *ppa 其实访问的就是 pa .
  • **ppa 先通过 *ppa 找到 pa ,然后对 pa 进行解引用操作: *pa ,那找到的是 a .

7、指针数组🙌

指针数组,顾名思义就是数组。指针数组,是用来存放指针的数组。数组我们已经知道整形数组,字符数组。那指针数组又是长什么样的呢?

int* arr3[5];

上述就是一个指针数组,arr3是数组名,一共有5个元素,每个元素的类型时int*。

接下来举几个栗子辅助大家理解:
可以利用指针数组来模拟二维数组的打印,但是这里有个区别是,二维数组的每一行元素在内存中是连续存放的,这里就不一定。

#include <stdio.h>
int main()
{int arr1[] = { 1,2,3,4,5 };int arr2[] = { 2,3,4,5,6 };int arr3[] = { 3,4,5,6,7 };int* ptr[] = {arr1, arr2, arr3};int i = 0;for (i = 0; i < 3; i++){int j = 0;for (j = 0; j < 5; j++){printf("%d ", ptr[i][j]);}printf("\n");}return 0;
}

程序运行结果图:
在这里插入图片描述
上述知识的一个综合运用栗子:

int main()
{int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };int i = 0;for (i = 0; i < 10; i++){printf("%d ", i[arr]);//i[arr] -- *(i+arr)//arr[i] -- *(arr+i)}//int* p = arr;//test(arr, 10);*(arr+i) -- *(p+i) -- arr[i]arr[i] --> *(arr+i) --> *(i+arr) -- i[arr]//for (i = 0; i < 10; i++)//{//	printf("%p = %p\n", &arr[i], p+i);//}return 0;
}int main()
{int arr[3][5];//arr[i][j]//(*(arr+i))[j]//*(*(arr+i)+j)return 0;
}

总结撒花💞

   本篇文章旨在分享C语言详解指针的相关知识点。希望大家通过阅读此文有所收获!😘如果我写的有什么不好之处,请在文章下方给出你宝贵的意见😊。如果觉得我写的好的话请点个赞赞和关注哦~😘😘😘

相关文章:

你是真的“C”——详解指针知识

你是真的“C”——详解指针知识&#x1f60e;前言&#x1f64c;1、 指针是什么&#xff1f;&#x1f64c;2、指针和指针类型&#x1f64c;2 、1指针-整数2 、 2指针的解引用3、 野指针&#x1f64c;3、 1野指针成因3、 2如何规避野指针4、指针运算&#x1f64c;4、1 指针-整数4…...

React/ReactNative面试攻略(偏RN)

useMemo Vs useCallBackuseMemo第一个参数返回的是值&#xff0c;useCallBack返回的是函数useMemo和useCallBack第二个参数都是依赖项useMemo避免组件非依赖项更新时参数的计算useCallback避免父组件非依赖项更新时造成子组件的重复渲染React.memo 使用场景纯prue组件&#xff…...

Leetcode-每日一题1234. 替换子串得到平衡字符串(滑动窗口 + 哈希表)

题目链接&#xff1a;https://leetcode.cn/problems/replace-the-substring-for-balanced-string/description/ 思路 题目意思 这题意思是一个只含有[Q, W, E, R] 四个字符的字符串s且长度一定是 4的倍数&#xff0c; 需要你通过替换子串&#xff0c;使他变成一个「平衡字符…...

linux命令小结-查看日志命令

一、查看日志命令cat查看文件 vi编辑后可以用cat进行查看保存是否成功1&#xff09;cat -n alert_monitor.log2&#xff09;cat -n alert_monitor.log | tail -n 100 | head -n 20 //查询100行之后的日志&#xff0c;且在100行之后里再查前20条日志more 可以通过回撤键翻页mor…...

Java知识点细节简易汇总——(8)枚举和注解+Java面向对象高级作业

一、枚举 自定义枚举 当我们使用 enum 关键字开发一个枚举类时&#xff0c;默认会继承 Enum 类, 而且是一个 final 类[如何证明],老师使用 javap 工具来演示传统的 public static final Season2 SPRING new Season2(“春天”, “温暖”); 简化成 SPRING(“春天”, “温暖”)…...

快速上手JVM- Java Virtual Machine面试不用慌

一、JVM的定义 JVM是Java Virtual Machine&#xff08;Java虚拟机&#xff09;的缩写&#xff0c;JVM是一种用于计算设备的规范&#xff0c;它是一个虚构出来的计算机&#xff0c;是通过在实际的计算机上仿真模拟各种计算机功能来实现的。 引入Java语言虚拟机后&#xff0c;J…...

安警官的IP地址是怎样定位到莽村附近的?

要说最近大火的电视剧非《狂飙》莫属。电视剧《狂飙》自开播以来&#xff0c;一举超过《三体》《去有风的地方》等先播电视剧&#xff0c;收视率一路“狂飙”&#xff0c;牢牢占据近期的收视冠军。 在剧中&#xff0c;张译扮演一名坚持公平、正义与理想的人民警察“安欣”&…...

STL中重要容器vector总结

你要尽全力保护你的梦想。那些嘲笑你的人&#xff0c;他们必定会失败&#xff0c;他们想把你变成和他们一样的人。如果你有梦想的话&#xff0c;就要努力去实现。 ——《当幸福来敲门》引言&#xff1a;C中STL里面的容器用法很巧妙&#xff0c;可以解决很多复杂的模型&#xff…...

11_会话原理与实现流程

1、会话的基本知识 # 会话## 1.会话是什么&#xff1f;客户端与服务器之间的对话交流## 2.为什么需要会话&#xff1f;-http 协议是无状态的&#xff08;六亲不认&#xff09;-同一用户多次访问同一网站&#xff0c;对网站来说&#xff0c;每次都是全新的-网站不能识别用户身份…...

Java测试——junit的使用(2)

排序 我们同一个类下的多个用例的执行顺序是不确定的&#xff0c;如果需要指定固定的顺序&#xff0c;则需要在类上加这个注解 TestMethodOrder(MethodOrderer.OrderAnnotation.class)然后在想要第一个执行的用例上加上 Order(1)第二个执行的用例上注解&#xff1a; Order(…...

数据库(六): MySQL的主从复制和读写分离

文章目录一、为什么要使用主从复制和读写分离二、主从复制的原理三、如何实现主从复制3.1 master配置3.2 slave配置3.3 测试主从复制四、读写分离五、缺点一、为什么要使用主从复制和读写分离 注意到主从复制和读写分离一般是一起使用的。目的很简单&#xff0c;就是提高数据库…...

编程思想-0x00架构

产生架构的原因&#xff1f; 1、代码均摊 将不同的代码进行分块&#xff0c;然后简历联系&#xff0c;低耦合、高内聚&#xff1b; 原则上&#xff1a;合理的App架构应该是合理分配每个类、结构体、方法、变量的存在都应该遵循单一职责的原则 2、便于测试 测试确保代码质量&…...

QCon演讲实录(上):多云环境下应用管理与交付实践

作者&#xff1a;阿里云大数据基础工程技术团队——郭耀星 大家上午好&#xff01;我是来自阿里云大数据基础工程技术团队的郭耀星&#xff0c;花名雪尧。今天我很高兴能够来到QCon&#xff0c;与大家分享我的经验和心得。在当前的多云环境中&#xff0c;作为运维支撑团队&…...

async thunk 解决 API 调用的依赖问题

async thunk 解决 API 调用的依赖问题 一句话节省看下面一堆内容的时间就是&#xff1a; async thunk 中可以使用 async/await 锁住其他的 action 操作 一般 API 之间存在三种情况&#xff1a; A 和 B 之间没有依赖关系 这样的情况下&#xff0c;A 和 B 可以各调用各的&#x…...

java 黑马头条 day3 实名认证分布式事务问题 seata

1 完善实名认证功能 1.1 实名认证分布式事务问题 1.1.1 问题分析 在昨天的实名认证代码中&#xff0c;审核完毕后添加 id5的演示异常&#xff0c;重新使用postman进行测试, 会发现 出现异常后 本地方法因为有 Transactional注解 对ap_user ap_user_realname的操作会回滚 而…...

测试开发之Django实战示例 第七章 创建电商网站

第七章 创建电商网站在上一章里&#xff0c;创建了用户关注系统和行为流应用&#xff0c;还学习了使用Django的信号功能与使用Redis数据库存储图片浏览次数和排名。这一章将学习如何创建一个基础的电商网站。本章将学习创建商品品类目录&#xff0c;通过session实现购物车功能。…...

【C++之容器篇】造轮子:list的模拟实现与使用

目录前言一、关于list1. 简介2. 成员类型二、默认成员函数1. 构造函数1. list()2. list(size_t n,const T& val T())和list(InputIterator first,InputIterator last)2. 拷贝构造函数3. 析构函数4. 赋值运算符重载函数三、迭代器1. 普通对象的正向迭代器2. const对象的正向…...

自动驾驶:决策规划算法岗位面经分享

本专栏分享 计算机小伙伴秋招春招找工作的面试经验和面试的详情知识点 专栏首页: 主要分享计算机算法类在面试互联网公司时候一些真实的经验 人情况是985本硕,硕士研究方向是强化学习在移动机器人路径规划中的应用,一段自动驾驶中小厂实习经历,秋招找的大都是机器人和自动驾…...

2.7、进程调度的时机、切换与过程、方式

1、进程调度的时机 进程调度\color{red}进程调度进程调度&#xff08;低级调度&#xff09;&#xff0c;就是按照某种算法从就绪队列中选择一个进程为其分配处理机 进程在操作系统内核程序临界区\color{red}操作系统内核程序临界区操作系统内核程序临界区中不能\color{red}不能…...

工程管理系统源码+项目说明+功能描述+前后端分离 + 二次开发

工程项目各模块及其功能点清单 一、系统管理 1、数据字典&#xff1a;实现对数据字典标签的增删改查操作 2、编码管理&#xff1a;实现对系统编码的增删改查操作 3、用户管理&#xff1a;管理和查看用户角色 4、菜单管理&#xff1a;实现对系统菜单的增删改查操…...

ESP32S3系列--SPI从机驱动详解(一)

一、目的 在之前的博文中《ESP32S3系列--SPI主机驱动详解(一)》、《ESP32S3系列--SPI主机驱动详解(二)》我们详细讲解了ESP32S3上的SPI外设如何工作在主机模式并通过代码的形式帮助大家理解。 本篇我们将介绍SPI外设工作在从机模式下的使用知识点。 二、介绍 参考资料 http…...

【实战篇】移动端H5网页在ios滑动不流畅和禁止缩放问题

问题描述:移动端H5网页在ios滑动不流畅和禁止缩放问题 最近开发小程序,有一个富文本展示页面使用的是<webview>H5网页嵌入的,当你用 overflow-y:scroll 属性的时候,内容超出容器溢出滚动的效果很迟顿,特别是在IOS系统中,而且页面还会缩放。 解决方案: 1…...

12 循环神经网络(基础篇) Basic RNN

文章目录问题引入关于权重权重共享RNN CellRNN原理RNN计算过程代码实现RNN Cell维度说明代码RNN维度说明NumLayers说明计算过程代码参考实例问题分析多分类问题代码RNN CellRNN改进Embedding网络结构Embedding说明Linear说明代码课程来源&#xff1a; 链接课程文本参考&#xf…...

【C语言必经之路——第11节】初阶指针(2)

五、指针的运算1、指针与整数相加减看一下下面的代码&#xff1a;#include<stdio.h> int my_strlen(char* str) {int count0;while(*str!\0){count;str;//指针加减整数}return count; } int main() {int lenmy_strlen("abcdef");printf("%d\n",len);…...

SpringBoot学习(1)第一个SpringBoot程序

之前的SpringMVc就不在记录了&#xff0c;好像时间不太够了&#xff0c;但是springmvc作为javaweb的升级学一学对于springboot还是有较大的帮助的。 首先我们需要引入依赖&#xff0c;但是请注意&#xff0c;其中的一个不算是依赖&#xff0c;写法有所不同 首先需要引入 <…...

什么是热迁移?90%的企业都理解错误

科技的发展&#xff0c;新冠的冲击&#xff0c;让市场竞争愈发激烈。尽管云计算服务为企业免除了基础硬件的建设和维护成本&#xff0c;当企业需要进行业务跨架调整、升级维护、环境测试等场景而进行云迁移&#xff0c;其过程中所带来的停机时间&#xff0c;就变得尤为头疼了。…...

Scratch少儿编程案例-丝滑版贪吃蛇

专栏分享 点击跳转=>Unity3D特效百例点击跳转=>案例项目实战源码点击跳转=>游戏脚本-辅助自动化点击跳转=>Android控件全解手册点击跳转=>Scratch编程案例👉关于作者...

Linux系统之网卡子接口配置方法

Linux系统之网卡子接口配置方法一、本地系统环境检查1.检查系统版本2.检查系统内核版本3.检查本地IP地址二、网卡子接口介绍1.网卡子接口简介2.网卡子接口的优点3.网卡子接口的缺点三 加载802.1q 模块1.查看系统802.1q 模块信息2.加载802.1q 模块3.检查802.1q 模块加载状态四、…...

2023上半年软考中级系统集成项目管理工程师2月25日开班

系统集成项目管理工程师是全国计算机技术与软件专业技术资格&#xff08;水平&#xff09;考试&#xff08;简称软考&#xff09;项目之一&#xff0c;是由国家人力资源和社会保障部、工业和信息化部共同组织的国家级考试&#xff0c;既属于国家职业资格考试&#xff0c;又是职…...

YOLO-V5轻松上手

之前介绍了YOLO-V1~V4版本各做了哪些事以及相较于之前版本的改进。有的人或许会想“直接学习最近版本的算法不好吗”&#xff0c;在我看来&#xff0c;每一个年代的版本/算法都凝聚着当年学术界的智慧&#xff0c;即便是它被淘汰了也依旧有值得思考的地方&#xff0c;或是可以使…...

唐山网站制作方案/电商项目策划书

二、 依赖属性的优先级 由于WPF 允许我们可以在多个地方设置依赖属性的值&#xff0c;所以我们就必须要用一个标准来保证值的优先级别。比如下面的例子中&#xff0c;我们在三个地方设置了按钮的背景颜色&#xff0c;那么哪一个设置才会是最终的结果呢&#xff1f;是Black、Red…...

石家庄微网站建设公司/湖北seo服务

什么是Node.js Node是一个服务器端JavaScript解释器。Node的目标是帮助程序员构建高度可伸缩的应用程序&#xff0c;编写能够处理数万条同时连接到一个物理机的连接代码。处理高并发和异步I/O是Node受到开发人员的关注的原因之一。 Node本身运行Google V8 JavaScript引擎&…...

网站做中英版/怎么做电商

2019独角兽企业重金招聘Python工程师标准>>> 参考了很多资料&#xff0c;说说自己对viewport的理解 viewport分visual viewport和layout viewport&#xff0c;visual viewport可以理解为移动设备屏幕的可视区域&#xff0c;visual viewport的大小可以理解为就是品目…...

佛山网页搜索排名提升/seo好seo

1.邮件传输和路由 邮件系统的主要功能是邮件传递&#xff0c;而邮件路由和传输完成了邮件在内部和外部的传递。 Exchange2007的管理员可以配置在组织内仅仅使用中心传输服务器来路由和传输邮件&#xff0c;或者使用中心传输服务器和边缘传输服务器来路由和传输邮件 当仅仅使用中…...

网站流量数据分析/吸引客人的产品宣传句子

查了一些资料也不是太明白两个的区别&#xff0c;但是前者是最安全的用法 打个简单的比方&#xff0c;你一个WEB程序&#xff0c;发布到Tomcat里面运行。首先是执行Tomcat org.apache.catalina.startup.Bootstrap类&#xff0c;这时候的类加载器是ClassLoader.getSystemClassLo…...

wordpress更新之后字体发生变化/杭州seo关键字优化

如何截取视频片段&#xff0c;只截取视频中间的一部分.我们从网上下载了一些视频&#xff0c;想要进行编辑&#xff0c;剪切之类的&#xff0c;往往会在选择软件上眼花缭乱。现在市面上有很多视频编辑的软件&#xff0c;有共享的&#xff0c;免费的&#xff0c;po解版的&#x…...