基础篇--指针

最近为了面试重新整理了下指针

1、指针是什么?

       指针(Pointer)就是内存的地址,C语言允许用一个变量来存放指针,这种变量称为指针变量。指针变量可以存放基本类型数据的地址,也可以存放数组、函数以及其他指针变量的地址。

       计算机中所有的数据都必须放在内存中,不同类型的数据占用的字节数不一样,例如 int 占用 4 个字节,char 占用 1 个字节。但是需要注意指针的长度与系统位数有关,32位系统占用4位字节,64位系统占用8位字节。

    int* p1;
    char *p2;
    // 输出int和char类型的数据长度
    std::cout << "sizeof(*p1)=" << sizeof(*p1) << "  sizeof(*p2)=" << sizeof(*p2) << std::endl;
    // 输出指针int*和char*类型的数据长度
    std::cout << "sizeof(p1)=" << sizeof(p1) << "  sizeof(p2)=" << sizeof(p2) << std::endl;

// 输出:
// sizeof(*p1)=4  sizeof(*p2)=1
// sizeof(*p1)=8  sizeof(*p2)=8 // 测试环境是x64

2、指针运算符 & 和 *

这里&是取地址运算符,*是间接运算符。

int p = 12;

&p 的运算结果是一个指针,指针所指向的地址就是 p 的地址;

指针的类型是 p 的类型加个*,指针所指向的类型是 p 的类型。

示例1:指针表达式

int a=12; 
int b; 
int *p; 
int **ptr;

// &a 的结果是一个指针,类型是int*,指向的类型是int,指向的地址是a 的地址。
p = &a; 

// *p 的类型是int,它所占用的地址是 p 所指向的地址,显然,*p 就是变量a。
*p = 24; 

// &p 的结果是个指针,该指针的类型是 p 的类型加个*,在这里是int **。
// 该指针所指向的类型是 p 的类型,这里是int*。该指针所指向的地址就是指针p 自己的地址。
ptr = &p; 


// *ptr 是个 int* 指针,&b 的结果也是个 int* 指针,
// 这两个指针的类型是一样的,所以用&b 来给*ptr 赋值就是毫无问题的了。
*ptr = &b; 

//*ptr 的结果是ptr 所指向的东西,在这里是一个指针,
//对这个指针再做一次*运算,结果是一个int 类型的变量。
**ptr=34; 

示例2:指针和数组

int array[10]={0,1,2,3,4,5,6,7,8,9},value;

value=array[0]; //也可写成:value=*array;

value=array[3]; //也可写成:value=*(array+3);

value=array[4]; //也可写成:value=*(array+4);

实例3:指针和结构体

指针指向结构体成员
int main()
{
    struct student st1, *st2;
    st2 = &st1;//指向结构体变量
    scanf("%s", st2->name);
    scanf("%d", &st2->score);
    printf("%s %d\n", st1.name, st1.score);
    printf("%s %d\n", (*st2).name, (*st2).score);
    printf("%s %d\n", st2->name, st2->score);
    return 0;
}
 
//输入: aha 12
//输出:aha 12
//     aha 12
//     aha 12

注意:

(1)如果要将一个结构体对象赋给一个结构体指针变量,那么它们的结构体类型必须相同

(2)指针 *st2 两边的括号不可省略,因为成员运算符“.”的优先级高于指针运算符“*”,所以如果 *st2 两边的括号省略的话,那么 *st2.name 就等价于 *(st2.name) 了。但是我们可以使用下面两种方式访问结构体成员:

(*指针变量名).成员名 

指针变量名->成员名

示例4:指针运算符

    int a[10] = {0,1,2,3,4,5,6,7,8,9};
    int* p = a;
    std::cout << "*p++=" << *p++ << "  *(p++)=" << *(p++) << "  (*p)++=" << (*p)++ << std::endl;

// 输出:*p++=1  *(p++)=1  (*p)++=0
  • *p++: 这个表达式先使用后递增。它先解引用指针 p,然后返回指针所指向的值。接着,指针 p 递增到下一个元素的位置。换句话说,它等效于 *(p++)

  • *(p++): 这个表达式也是先使用后递增。它先将指针 p 的当前值用于解引用,然后返回该位置上的值。接着,指针 p 递增到下一个元素的位置。

  • (*p)++: 这个表达式首先解引用指针 p,然后对指针所指向的值进行递增操作。它相当于对指针所指向的值进行后递增操作。换句话说,它会递增 p 所指向的值,并且该递增操作会改变原始值。

3、错误用法总结

  • 一个函数想修改另一个函数的值,必须传指针和解引用

  • 野指针、空悬指针:没有访问权限的地址

  • 空指针(NULL):表示当前指针无效

错误1:将整数值赋值给指针变量

// 错误的将整数值赋值给指针变量
int *p = 6;

// 修正用法:
int* p = NULL;   // 声明一个指向整数的指针
int value = 6;   // 声明一个整数变量并赋值为 6

p = &value;   // 将 'value' 的地址赋给指针 'p'

错误2:函数参数通过值传递传递不会影响到原始的参数

Swap 函数接收两个整数参数 a 和 b,但并没有使用指针进行交换操作。在这种情况下,函数参数 a 和 b 是通过值传递传递进来的,而函数内部对它们的操作不会影响到原始的参数。

void Swap(int a, int b)//未传指针
{
    int tmp = a;
    a = b;
    b = tmp;
}

错误3:没有解引用

在函数内部,你只是对指针进行了赋值操作,并没有对指针所指向的值进行交换。这种情况下,指针变量 a 和 b 的交换并不会影响原始的指针指向的值。!

void Swap(int* a, int* b)//未解引用
{
    int *tmp = a;
    a = b;
    b = tmp;
}

修正后

void Swap(int* a, int* b)
{
    int tmp = *a;
    *a = *b;
    *b = tmp;
}

错误4、野指针

tmp的值未初始化,没有申请tmp指针指向的内存空间

void Swap(int* p1, int* p2)//有野指针 tmp的值未初始化
{
    int* tmp;
    *tmp = *p1;
    *p1 = *p2;
    *p2 = *tmp;
}

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

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

相关文章

如何评估户外LED显示屏的质量标准

随着数字媒体的不断进步&#xff0c;户外LED显示屏已经成为现代城市不可或缺的一部分&#xff0c;它们以鲜明的视觉冲击力和广泛的应用范围&#xff0c;成为了广告和公共信息传播的重要工具。然而&#xff0c;并非所有的户外LED显示屏都能满足高标准的户外使用要求。为了确保投…

MoonBit MeetUp回顾——张正、宗喆:编程语言在云原生与区块链领域的技术探索

宗喆和张正分别给我们带了 KCL 相关的最新进展&#xff0c;由蚂蚁集团开发的 Rust 编写的开源 DSL&#xff0c;目标是优化云原生策略配置和用户体验。它通过引入动态配置管理、配置校验和基础设施抽象等核心概念&#xff0c;解决开发者认知负担、配置膨胀和标准化工具缺乏的问题…

国内外主要气象卫星介绍

NOAA AVHRR介绍 美国NOAA极轨卫星从1970年12月第一颗发射以来&#xff0c;近40年连续发射了18颗&#xff0c;最新的NOAA-19也将在2009年发射升空。NOAA卫星共经历了5代&#xff0c;目前使用较多的为第五代NOAA卫星&#xff0c;包括NOAA-15—NOAA-18&#xff1b;作为备用的第四…

【STM32CubeMX(1)】开发环境搭建

1、安装STM32CubeMX 安装前言&#xff1a;软件是免费的&#xff0c;网上安装教程也是很丰富&#xff0c;我就不造轮子了。 1.1 准备java-jdk环境 参考&#xff1a;Java环境配置|菜鸟教程 1.2 下载STM32CubeMX 获取安装包&#xff1a;STM32CubeMX - STM32Cube initializati…

verilog 从入门到看得懂---verilog 的基本语法各种语句

本篇文章主要介绍verilog里面常用的语句&#xff0c; 包括条件语句、循环语句块语句和生成语句。出了块语句和生成语句&#xff0c;其他的基本和c语言或者m语言一致。 1&#xff0c;if 语句&#xff0c;在需要判断逻辑的时候可以使用if语句&#xff0c;如 从输入a&#xff0c;…

SpringCloud实用篇(一)

1.SpringCloud SpringCloud是目前国内使用最广泛的微服务框架。官网地址&#xff1a;Spring Cloud SpringCloud集成了各种微服务功能组件&#xff0c;并基于SpringBoot实现了这些组件的自动装配&#xff0c;从而提供了良好的开箱即用体验&#xff1a; SpringCloud与SpringBoo…

Python中的排序算法:归并排序,选择排序和快速排序详解

排序算法是计算机科学中的一个基础且重要的概念。它用于将一组数据&#xff08;如数字、字符串等&#xff09;按照某种顺序&#xff08;升序或降序&#xff09;重新排列。在Python中&#xff0c;我们有许多内置的函数和库可以方便地实现排序&#xff0c;但理解排序算法的基本思…

Netty对Channel事件的处理以及空轮询Bug的解决

继续上一篇Netty文章&#xff0c;这篇文章主要分析Netty对Channel事件的处理以及空轮询Bug的解决 当Netty中采用循环处理事件和提交的任务时 由于此时我在客户端建立连接&#xff0c;此时服务端没有提交任何任务 此时select方法让Selector进入无休止的阻塞等待 此时selectCnt进…

企业员工培训考试系统开发方案

一、引言 在当今知识经济时代&#xff0c;企业对员工的综合素质和专业技能有着越来越高的要求。为了适应这一趋势&#xff0c;构建一个全面而高效的企业员工培训考试系统变得尤为重要。该系统旨在通过提供多样化的培训课程和全面的考核机制&#xff0c;促进员工持续学习和能力…

24/03/28总结

抽象类&#xff1a; 将共性的方法抽取到父类之后。由于每一个子类执行的内容是不一样&#xff0c;所以&#xff0c;在父类中不能确定具体的方法体。该方法就可以定义为抽象方法。 而为什么不直接在子类中定义方法&#xff1a;项目的完成不是一个人&#xff0c;如果有时忘记写方…

【教学类-40-09】A4骰子纸模制作9.0(3.47CM嵌套骰子 一条8格便于对折,表格相连 一页3个 油墨打印A4铅画纸)

作品展示 背景需求&#xff1a; 骰子调整到第8版&#xff0c;把骰子图案作成一长条&#xff0c;便于切割裁剪。 【教学类-40-08】A4骰子纸模制作8.0&#xff08;2.97CM嵌套骰子表格相连 一页7个 油墨打印A4铅画纸&#xff09;-CSDN博客文章浏览阅读929次&#xff0c;点赞20次…

幻兽帕鲁服务器价格表_阿里云/腾讯云/京东云/华为云报价大全

2024年全网最全的幻兽帕鲁服务器租用价格表&#xff0c;阿里云幻兽帕鲁游戏服务器26元1个月、腾讯云32元一个月、京东云26元一个月、华为云24元1个月&#xff0c;阿腾云atengyun.com整理最新幻兽帕鲁专用4核16G、8核16G、8核32G游戏服务器租用价格表大全&#xff1a; 阿里云幻…

土壤有机质空间分布数据

土壤有机质&#xff08;soil organic matter&#xff09;是土壤中含碳有机化合物的总称&#xff0c;包括土壤固有的和外部加入的所有动植物残体及其分解产物和合成产物。主要来源于动植物及微生物残体&#xff0c;可分为腐殖质和非腐殖物质。一般占土壤固相总重的10%以下&#…

推荐:便宜幻兽帕鲁Palworld联机游戏服务器优惠价格表

2024年全网最全的幻兽帕鲁服务器租用价格表&#xff0c;阿里云幻兽帕鲁游戏服务器26元1个月、腾讯云32元一个月、京东云26元一个月、华为云24元1个月&#xff0c;阿腾云atengyun.com整理最新幻兽帕鲁专用4核16G、8核16G、8核32G游戏服务器租用价格表大全&#xff1a; 阿里云幻…

思维升级之路:观察思维深层,解锁认知新境界

目录 一、观察我们的思维习惯 二、人类有哪些思维方法 三、为什么要多使用归纳推理而不是演绎推理 四、转变思维的关键 - 觉察 怎么提升自身的认知水平&#xff1f;这篇文章里&#xff0c;作者尝试对思维模式这件事做出探讨&#xff0c;一起来看看&#xff0c;或许可以帮你…

2023年蓝桥杯省赛——矩形面积总和

目录 题目链接&#xff1a; 1.矩形总面积 - 蓝桥云课 (lanqiao.cn) 思路 暴力 数学杯思路 数学逻辑 难点之重合区域 代码实现 总结 题目链接&#xff1a; 1.矩形总面积 - 蓝桥云课 (lanqiao.cn) 思路 暴力 开幕雷击&#xff0c;我直接开始暴力&#xff0c;但是我暴力…

Java学习之方法

目录 方法 方法声明格式&#xff1a; 调用方式&#xff1a; 详细说明 示例 --方法的声明及调用 语句块 练习 方法的重载(overload) 构成条件 示例 --方法重载 递归结构 缺陷 方法 方法(method)&#xff1a;一段用于完成特定功能的代码片段&#xff0c;类似于其他语…

Redis命令-List命令

4.6 Redis命令-List命令 Redis中的List类型与Java中的LinkedList类似&#xff0c;可以看做是一个双向链表结构。既可以支持正向检索和也可以支持反向检索。 特征也与LinkedList类似&#xff1a; 有序元素可以重复插入和删除快查询速度一般 常用来存储一个有序数据&#xff…

算法系列--动态规划--背包问题(2)--01背包拓展题目

&#x1f495;"2024.3.28小米汽车发布"&#x1f495; 作者&#xff1a;Lvzi 文章主要内容&#xff1a;算法系列–动态规划–背包问题(2)–01背包拓展题目 大家好,今天为大家带来的是算法系列--动态规划--背包问题(2)--01背包拓展题目 1.分割等和⼦集 链接: https:/…

能够解析任何编程语言的开源语法解析树 | 开源日报 No.171

tree-sitter/tree-sitter Stars: 14.6k License: MIT tree-sitter 是一个用于编程工具的增量解析系统。 该项目的主要功能、关键特性、核心优势包括&#xff1a; 通用性&#xff0c;能够解析任何编程语言高效性&#xff0c;能够在文本编辑器中每次按键都进行解析健壮性&…
最新文章