C语言之指针的指向地址和指针的内容总结(八十九)

news2024/11/17 12:19:51

简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长!

优质专栏:Audio工程师进阶系列原创干货持续更新中……】🚀
优质专栏:多媒体系统工程师系列原创干货持续更新中……】🚀
优质视频课程:AAOS车载系统+AOSP14系统攻城狮入门实战课原创干货持续更新中……】🚀

人生格言: 人生从来没有捷径,只有行动才是治疗恐惧和懒惰的唯一良药.

更多原创,欢迎关注:Android系统攻城狮

欢迎关注Android系统攻城狮

1.前言

本篇目的:C语言之指针的指向和指针的内容总结

2.C语言指针介绍

  • C语言中的指针,可以说是其最具特色且最具挑战性的部分。指针在C语言中起着至关重要的作用,它允许我们直接访问内存地址,并对存储在那些地址中的数据进行操作。下面,我们将对C语言中的指针进行详细的介绍。

  • 首先,我们需要明白指针是什么。在C语言中,指针是一个变量,其值为另一个变量的地址,即内存位置的直接地址。通过指针,我们可以直接访问和修改存储在特定内存地址中的数据,这使得我们能够进行诸如动态内存分配、函数参数传递等高级操作。

  • 其次,使用指针可以带来许多便利。例如,在函数参数传递时,如果我们需要修改一个变量的值,可以通过指针传递该变量的地址,然后在函数内部通过这个地址来修改变量的值。这种方式可以避免复制大量的数据,提高程序的效率。此外,指针还可以用于实现数组、字符串、链表等数据结构,以及进行文件操作等。

  • 然而,指针的使用也带来了一些风险。如果指针没有被正确初始化,或者指向了错误的内存地址,就可能导致程序崩溃或者数据损坏。因此,在使用指针时,我们需要格外小心,确保指针指向了正确的内存地址,并且在不再需要指针时及时释放其占用的内存。

  • 此外,C语言中的指针还有许多高级用法,如指向函数的指针、指向指针的指针(即二级指针)等。这些高级用法使得C语言能够实现更为复杂和灵活的功能,但同时也增加了编程的难度和复杂性。

  • 总的来说,C语言中的指针是一把双刃剑,既带来了强大的功能和便利,也带来了风险和挑战。只有深入理解和掌握指针的使用方法和注意事项,我们才能充分利用C语言的强大功能,编写出高效、稳定、安全的程序。

3.代码实例

需求:使用get函数将,"456"字符串返回。

<1>.v1.0 指针指向字符串常量

#include <stdio.h>
#include <cstdlib>
#include <string.h>

void get(char *name) {
  name = "345";
}

int main() {
  char data[64] = "123"; 
  get(data);
  printf("data = %s\n", data); 
  return 0;
}

  • 结论:以上实现不能完成"456"字符串的需求。
  • 原因:
  • 在C/C++中,函数参数传递是按值传递的,这意味着函数接收到的参数实际上是原始数据的副本。当你在函数内部修改参数时,只会修改副本的值,而不会影响原始数据。
  • 在 get 函数中,name = “345”; 这行代码实际上只是将指针 name 指向了字符串常量 "345" 的地址而不是修改了原始数据
  • 我们来打印一下指针本身的地址和指向的地址验证下。
#include <stdio.h>
#include <cstdlib>
#include <string.h>

void get(char *name) {
  printf("xxx--------------->line = %d, &name = %p, name = %p\n",__LINE__,&name,name);
  name = "345";
  printf("xxx--------------->line = %d, &name = %p, name = %p\n",__LINE__,&name,name);
}

int main() {
  char data[64] = "123";
  printf("xxx--------------->line = %d, &data = %p, data = %p\n",__LINE__,&data,data);
  get(data);
  printf("data = %s\n", data);
  return 0;
}

打印:
xxx--------------->line = 13, &data = 0x7ffc176d7870, data = 0x7ffc176d7870
xxx--------------->line = 6, &name = 0x7ffc176d7858, name = 0x7ffc176d7870
xxx--------------->line = 8, &name = 0x7ffc176d7858, name = 0x55f7443e903d
data = 123

结果:
在 name = “345"后,name指向的地址由0x7ffc176d7870改变为0x55f7443e903d,并没有改变原来name指向地址的0x7ffc176d7870内容,所以不能返回"345”,因为在get函数中,改变name指针的地址是局部的,随着get函数调用结束,也随之被释放内存。

<2>.v2.0 修改指针指向地址的内容

#include <stdio.h>
#include <cstdlib>
#include <string.h>

void get(char *name) {
  printf("xxx--------------->line = %d, &name = %p, name = %p\n",__LINE__,&name,name);
  memcpy(name, "456", 3);
  printf("xxx--------------->line = %d, &name = %p, name = %p\n",__LINE__,&name,name);
}

int main() {
  char data[64] = "123";
  printf("xxx--------------->line = %d, &data = %p, data = %p\n",__LINE__,&data,data);
  get(data);
  printf("data = %s\n", data);
  return 0;
}

  • 结论:以上实现可以完成"456"字符串的需求。
  • memcpy(name, "456", 3);
  • 这行代码使用 memcpy 函数将字符串 “456” 的前3个字符复制到 name 指针所指向的内存空间中。
  • 通过这个操作,原始的字符串 “123” 被修改为了 “456”。
  • 因为 name 指针指向了 data 数组的起始位置,所以这行代码会修改 data 数组的内容。
  • 总的来说,name = “345”; 操作并不会修改原始数据,而 memcpy(name, “456”, 3); 操作会修改原始数据。
  • 如果你想要修改原始数据,你应该直接使用 memcpy 函数或类似的函数来修改参数所指向的内存内容;而不是让指针指向新的地址。

打印:
xxx--------------->line = 13, &data = 0x7ffd2f00f040, data = 0x7ffd2f00f040
xxx--------------->line = 6, &name = 0x7ffd2f00f028, name = 0x7ffd2f00f040
xxx--------------->line = 8, &name = 0x7ffd2f00f028, name = 0x7ffd2f00f040
data = 456

结果:这次修改了指针name指向的内容,而并没有修改name的指向,从第6行和第8行,打印可以看出指向的地址是0x7ffd2f00f040,并且没有改变。

<3>.name本身的地址&name为何改变?

  • 可能有读者发现了&data到&name传给get函数是,发现name本身的地址改变了,这是为什么呢?
  • 虽然 name 指针指向的内容是 data 数组的起始地址,但name 指针本身(地址)在 get 函数中是一个局部变量,它在栈上分配,因此其地址可能不同于在 main 函数中传递给它的地址。
  • 因此,&name 的值在 get 函数中可能会不同于 main 函数中传递给它的地址,这取决于编译器如何分配栈上的变量。
  • 总的来说,&name 的值不影响函数的行为,因为 get 函数接收到了正确的 data 数组的起始地址,可以正确地访问和操作数组的内容。

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

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

相关文章

全国加油站分布数据/停车场分布/公园分布/景区分布/保护区分布/poi感兴趣点

加油站是指为汽车和其它机动车辆服务的、零售汽油和机油的补充站&#xff0c;一般为添加燃料油、润滑油等。由于加油站所销售的石油商品具有易燃爆、易挥发、易渗漏、易集聚静电荷的特性&#xff0c;故加油站以“安全”为第一准则。在加油站内严禁烟火&#xff0c;严禁从事可能…

SpringMVC --- 老杜

1、什么是SpringMVC&#xff1f; SpringMVC是一个基于Java实现了MVC设计模式的请求驱动类型的轻量级Web框架&#xff0c;通过把Model&#xff0c;View&#xff0c;Controller分离&#xff0c;将web层进行职责解耦&#xff0c;把复杂的web应用分成逻辑清晰的及部分&#xff0c;…

java中大型医院HIS系统源码 Angular+Nginx+SpringBoot云HIS运维平台源码

java中大型医院HIS系统源码 AngularNginxSpringBoot云HIS运维平台源码 云HIS系统是一款满足基层医院各类业务需要的健康云产品。该产品能帮助基层医院完成日常各类业务&#xff0c;提供病患预约挂号支持、病患问诊、电子病历、开药发药、会员管理、统计查询、医生工作站和护士工…

Gson的用法

1. 导入依赖 <dependency><groupId>com.google.code.gson</groupId><artifactId>gson</artifactId><version>2.8.6</version> </dependency> 2. 使用Gson进行解析 2.1 Gson解析普通对象 package com.jiang.partnetbackend.…

Studio One 6注册机下载安装激活教程

一、Studio One 6安装 StudioOne6 下载&#xff1a;https://souurl.cn/Y6ZWCY StudioOne6 Win/Mac版注册机下载&#xff1a; rack百度网盘&#xff1a;https://pan.baidu.com/s/1zX3DqXt-wsy510L1lDI7Xg 提取码&#xff1a;3phh 1.双击Studio One6安装包&#xff0c;如下图&…

Qt中的事件学习笔记

视频链接 https://www.bilibili.com/video/BV18B4y1K7Cs/?spm_id_from333.999.0.0&vd_sourcefa4ef8f26ae084f9b5f70a5f87e9e41b事件 Qt主要用来开发带窗口的应用程序&#xff0c;我们使用的窗口的应用程序都是基于时间&#xff08;比如安卓中的点击事件&#xff09;&…

【机器学习】机器学习创建算法第4篇:K-近邻算法,学习目标【附代码文档】

机器学习&#xff08;算法篇&#xff09;完整教程&#xff08;附代码资料&#xff09;主要内容讲述&#xff1a;机器学习算法课程定位、目标&#xff0c;K-近邻算法定位,目标,学习目标,1 什么是K-近邻算法,1 Scikit-learn工具介绍,2 K-近邻算法API。K-近邻算法&#xff0c;1.4 …

手术麻醉系统源码 医疗信息管理系统源码C#.net6.0+ vs2022,vscode+BS网页版 手麻系统源码

手术麻醉系统源码 医疗信息管理系统源码C#.net6.0 vs2022,vscodeB/S网页版 手麻系统源码 手术麻醉管理系统是应用于医院手术室、麻醉科室的计算机软件系统。该系统针对整个围术期&#xff0c;对病人进行全程跟踪与信息管理&#xff0c;自动集成病人HIS、LIS、RIS、PACS信息&…

第四百四十三回

文章目录 1. 概念介绍2. 思路与方法2.1 整体思路2.2 使用方法 3. 示例代码4. 内容总结 我们在上一章回中介绍了"自定义Action菜单"相关的内容&#xff0c;本章回中将介绍如何获取屏幕相关参数.闲话休提&#xff0c;让我们一起Talk Flutter吧。 1. 概念介绍 我们在本…

【面试八股总结】进程(一)

参考资料 &#xff1a;小林Coding、阿秀、代码随想录 一、什么是进程&#xff1f; 1. 基本概念 进程是具有独立功能的程序在一个数据集合上运行的过程&#xff0c;是系统进行资源分配和调度的一个独立单位。 2. 进程控制块 系统通过进程控制块PCB描述进程的进本情况…

[Spring Cloud] gateway全局异常捕捉统一返回值

文章目录 处理转发失败的情况全局参数同一返回格式操作消息对象AjaxResult返回值状态描述对象AjaxStatus返回值枚举接口层StatusCode 全局异常处理器自定义通用异常定一个自定义异常覆盖默认的异常处理自定义异常处理工具 在上一篇章时我们有了一个简单的gateway网关 [Spring C…

vue3中实现文本显示省略号和tooltips提示框

前言 在 B 端业务中&#xff0c;我们经常会遇到文本内容超出容器区域需显示省略号的需求。当鼠标移入文本时&#xff0c;会出现 Tooltip 显示完整内容。最近&#xff0c;我也遇到了这样的场景。为了提高业务通用性&#xff0c;我已将其封装为组件、Hook 和指令等形式供使用。 …

从0到1实现RPC | 04 负载均衡和静态注册中心

一、Router的定义 Router路由用于预筛选&#xff0c;Dubbo有这样的设计&#xff0c;SpringCloud没有。 二、LoadBanlancer定义 负载均衡器&#xff1a;默认取第一个 当前支持随机和轮询两种负载均衡器。 随机&#xff1a;从所有provider中随机选择一个。 轮询&#xff1a;每…

如何选择优质的静动态住宅代理IP提供商

在从事跨境电商业务时选择优质的静动态住宅代理IP提供商是一个涉及多个方面考量的过程。在进行选择时&#xff0c;需要综合考虑多种因素&#xff0c;以确保选择的提供商能够满足您的需求并提供稳定、可靠的服务。以下是一些建议&#xff0c;以帮助您进行选择&#xff1a; 第一…

js中使let关键字报错,改用var关键字解决

js中使let关键字报错,改用var关键字解决 项目场景&#xff1a;问题描述原因分析&#xff1a;解决方案&#xff1a;总结 项目场景&#xff1a; 使用 let 关键字报错&#xff0c;报错信息为&#xff1a; Uncaught ReferenceError: maxNum is not defined at getMaxNum (4-3.htm…

独角数卡对接支付卡跳转问题解决方法

问题描述 最近在用独角数卡搭建了一个测试版的商店程序&#xff0c;结果却在对接易支付的过程中出现了卡跳转的问题&#xff0c;支付能正常完成&#xff0c;订单发卡也正常&#xff0c;就是会卡在这个弹窗页面无法正常跳转至订单查看页面。 本来这种BUG无关痛痒&#xff0c;但…

蓝桥杯(5):python动态规划DF[2:背包问题]

1 0-1背包介绍【每件物品只能拿1件或者不拿】 1.1 简介 贪心是不可以的&#xff01;&#xff01;&#xff01; 1.2 状态 及状态转移 转移解释&#xff1a;要么不选 则上一个直接转移过来【dp[i-1][j]】&#xff0c;要么是选这个之后体积为j 则上一个对应的就是【dp[i-1][j-wi]…

阿里云邮件服务器多少钱?邮件服务器租用费用

阿里云邮件服务器租用费用&#xff0c;2核2G3M带宽99元一年、2核4G4M服务器199元一年&#xff0c;不只是云服务器ECS&#xff0c;还可以选择轻量应用服务器。 0、在阿里云CLUB中心领取 aliyun.club 当前最新的优惠券和服务器报价单 1、阿里云服务器ECS经济型e实例&#xff0c;2…

leetcode代码记录(买卖股票的最佳时机

目录 1. 题目&#xff1a;2. 我的代码&#xff1a;小结&#xff1a; 1. 题目&#xff1a; 给定一个数组 prices &#xff0c;它的第 i 个元素 prices[i] 表示一支给定股票第 i 天的价格。 你只能选择 某一天 买入这只股票&#xff0c;并选择在 未来的某一个不同的日子 卖出该股…

导入项目运行后,报错java: Cannot find JDK ‘XX‘ for module ‘XX‘

解决方案&#xff1a; 1、删除.idea和.iml文件 2、右击此module&#xff0c;点击 Open Module Settings 在 Module SDK 中选择所安装的java版本后&#xff0c;点击右下角 Apply 3、再运行试试吧&#xff0c;成功&#xff01;