C语言指针(Pointer)

news2024/9/19 9:00:21

指针与底层硬件联系紧密,使用指针可操作数据的地址,实现数据的间接访问

问题:这好好的一个变量,我定义完之后为啥不用它名字直接访问呢?我非要用间接访问,这不没事找事吗?

为什么需要指针?

  • 指针的使用使得不同区域的代码可以轻易的共享内存数据。当然你也可以通过数据的复制达到相同的效果,但是这样往往效率不太好,因为诸如结构体等大型数据,占用的字节数多,复制很消耗性能。但使用指针就可以很好的避免这个问题,因为任何类型的指针占用的字节数都是一样的(根据平台不同,有4字节或者8字节或者其他可能) 
  • 指针使得一些复杂的链接性的数据结构的构建成为可能,比如链表,链式二叉树等等
  • 有些操作必须使用指针。如操作申请的堆内存
  • C语言中的一切函数调用中,实参传递给形参的机理都是“按值传递(pass by value)”,如果我们要在函数中修改被传递过来的对象,就必须通过这个对象的指针来完成

 

定义指针 

用来保存 指针(地址) 的变量,就是指针变量。如果指针变量p1保存了变量 num的地址,则就说:p1指向了变量num 

指针即指针变量,用于存放其他数据单元(变量/数组/结构体/函数等)的首地址。若指针存放了某个数据单元的首地址,则这个指针指向了这个数据单元,若指针存放的值是0,则这个指针为空指针 

16位系统:x=2,32位系统:x=4,64位系统:x=8 

在系统中,指针占用的字节数(即指针的大小)是固定的。这是因为指针的大小主要由CPU的架构和操作系统的内存管理模式决定!因为指针的作用就是把地址表示出来

不同系统的int占的字节数确实可能会变化!在C语言中,int类型的大小可以在不同的编译器和硬件平台上有所不同

误区:

所以我们应该把*放在p前面,这样可以更好区分数据类型

int *p,p1;		//定义一个指向int*型数据的指针和一个int类型的p1

实际上int*是一个整体和其他数据类型一样!!! 

这是因为C的语法规定了在声明多个变量时,只有第一个变量前的类型修饰符(如*表示指针)会应用到所有后面声明的变量上,除非这些变量被明确地指定了不同的类型或修饰符。 

在C语言中,定义变量时,在变量名前写一个 * 星号,这个变量就变成了对应变量类型的指针变量。必要时要加( ) 来避免优先级的问题 

int (* parr )[3]; //parr是一个指向【包含3个int元素的数组】的指针变量

指针的操作

取地址:既然有了指针变量,那就得让他保存其它变量的地址,使用& 运算符取得一个变量的地址

int add(int a , int b)
{
    return a + b;
}

int main(void)
{
    int num = 97;
    float score = 10.00F;
    int arr[3] = {1,2,3};

    //-----------------------

    int* p_num = #
    float* p_score = &score;
    int (*p_arr)[3] = &arr;           
    int (*fp_add)(int ,int )  = &add;  //p_add是指向函数add的函数指针
    return 0;
}

特殊的情况,他们并不一定需要使用&取地址:

  • 数组名的值就是这个数组的第一个元素的地址。
  • 函数名的值就是这个函数的地址。
  • 字符串字面值常量作为右值时,就是这个字符串对应的字符数组的名称,也就是这个字符串在内存中的地址。

 

#include <stdio.h>  
  
int main() {  
    int arr[10] = {0};  
    printf("%p\n", (void*)arr); // 打印数组的地址,等同于&arr[0]  
    printf("%p\n", (void*)&arr[0]); // 显式地获取第一个元素的地址  
}

数组与指针 

数组名就是指针变量! 

数组是一些相同数据类型的变量组成的集合,其数组名即为指向该数据类型的指针。数组的定义等效于申请内存、定义指针和初始化 

char c[ ] = {0x33, 0x34, 0x35};

利用下标引用数组数据也等效于指针取内容: 

#include <iostream>
using namespace::std;
int main()
{
	char c[] = { 0x33, 0x34, 0x35 };
	if (c[0]==*c)
	{
		cout << "true\n";
	}
	if (c[1] == *(c+1))
	{
		cout << "true";
	}
}

注意事项 

在对指针取内容之前,一定要确保指针指在了合法的位置,否则将会导致程序出现不可预知的错误 !!!

引用空指针
尝试访问或修改空指针所指向的内存是未定义行为,通常会导致程序崩溃

int *ptr = NULL;  
*ptr = 10; // 错误:解引用空指针

未初始化的指针
未初始化的指针可能包含任何值,包括NULL或垃圾值。如果假设这样的指针不是NULL并尝试使用它,可能会导致不可预测的行为

int *ptr;  
*ptr = 20; // 错误:ptr可能不是NULL,但也不是有效的内存地址

忘记检查返回值
某些函数(如动态内存分配函数malloccallocrealloc)在失败时会返回NULL。如果忘记检查这些函数的返回值,可能会错误地解引用一个空指针

int *ptr = malloc(10 * sizeof(int));  
if (!ptr) {  
    // 处理错误  
}  
// 如果省略了上面的if语句,直接使用ptr可能会导致问题

错误的指针算术
对空指针进行算术运算(如递增或递减)在C语言中是未定义的。虽然大多数现代编译器会将这些操作视为无操作(即空指针保持不变),但依赖这种未定义行为是不安全的

int *ptr = NULL;  
ptr++; // 错误:对空指针进行算术运算

错误的比较
虽然将指针与NULL进行比较是常见的做法,但错误地将指针与整数0或错误的指针值进行比较可能会导致问题

int *ptr = NULL;  
if (ptr == 0) { // 正确,但不如使用NULL直观  
    // ...  
}  
if (ptr == (void*)0) { // 冗余且可能令人困惑  
    // ...  
}

野指针
野指针是指向已经被释放的内存的指针。虽然野指针本身不一定是NULL,但使用野指针(尤其是假设它指向有效内存)的行为与解引用空指针一样危险。

多重释放
尝试释放一个已经被释放的指针(即使它之后被设置为NULL)也是错误的。这可能导致堆损坏或程序崩溃。

指针的应

指针的应用

传递参数

使用指针传递大容量的参数,主函数和子函数使用的是同一套数据,避免了参数传递过程中的数据复制,提高了运行效率,减少了内存占用。

使用指针传递输出参数,利用主函数和子函数使用同一套数据的特性,实现数据的返回,可实现多返回值函数的设计

直接访问物理地址下的数据

访问硬件指定内存下的数据,如设备ID号等 

将复杂格式的数据转换为字节,方便通信与存储

传递返回值 

将模块内的公有部分返回,让主函数持有模块的“句柄”,便于程序对指定对象的操作 

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

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

相关文章

18.C语言函数相关练习题2

函数相关练习题2 1.不同班级的平均分2.二维数组和函数的概念3.外部变量和全局变量4.全局变量的例子5.输入10个数&#xff0c;找出最大数及最大数的下标 1.不同班级的平均分 #include <stdio.h>void inityarry(int arr[],int len){int i;for(i0;i<len;i){printf("…

【第八天】DNS及其查询过程

DNS及其查询过程 什么是DNS&#xff1f; 一般我们的主机&#xff0c;服务器都有一个ip地址&#xff0c;例如10.10.10.1。在计算机层面&#xff0c;如果我们要发送请求的话&#xff0c;首先就要知道我们的目标&#xff0c;也就是对方的ip地址。而IP地址很难记&#xff0c;比如…

初学者编程指南:方法与资源推荐

一、引言 编程已成为当代大学生的必备技能&#xff0c;但面对众多编程语言和学习资源&#xff0c;新生们常常感到迷茫。如何选择适合自己的编程语言&#xff1f;如何制定有效的学习计划&#xff1f;如何避免常见的学习陷阱&#xff1f;编程不仅是技术领域的一项基本技能&#…

H.264编码中的16x16宏块分析

&#x1f60e; 作者介绍&#xff1a;欢迎来到我的主页&#x1f448;&#xff0c;我是程序员行者孙&#xff0c;一个热爱分享技术的制能工人。计算机本硕&#xff0c;人工制能研究生。公众号&#xff1a;AI Sun&#xff08;领取大厂面经等资料&#xff09;&#xff0c;欢迎加我的…

快速索引alarm添加

快速索引alarm添加 添加预警alarm 文件夹和 temp_led.c , temp_led.h , humi_led.c, humi_led.h (1)点击品字, 添加alarm, 然后增加文件, 点进Source文件夹 (2)点击新建文件夹, 然后新建alarm文件夹 (3)把文件类型切换为all, 方便后续右键添加上述四个文件名字. (4)空白处, 右…

社区团购的全流程解析与开源AI智能名片S2B2C商城小程序的应用探索

摘要&#xff1a;随着互联网技术的飞速发展&#xff0c;社区团购作为一种新兴的电商模式&#xff0c;凭借其高效、便捷、低成本的优势迅速崛起。本文旨在深入探讨社区团购的交易全流程&#xff0c;并以开源AI智能名片S2B2C商城小程序为例&#xff0c;分析其在社区团购中的创新应…

Nginx进阶-常见配置

一、nginx Proxy 反向代理 1、代理原理 反向代理产生的背景&#xff1a; 在计算机世界里&#xff0c;由于单个服务器的处理客户端&#xff08;用户&#xff09;请求能力有一个极限&#xff0c;当用户的接入请求蜂拥而入时&#xff0c;会造成服务器忙不过来的局面&#xff0c…

计算机毕业设计选题推荐-预制菜平台-Java/Python项目实战

✨作者主页&#xff1a;IT毕设梦工厂✨ 个人简介&#xff1a;曾从事计算机专业培训教学&#xff0c;擅长Java、Python、微信小程序、Golang、安卓Android等项目实战。接项目定制开发、代码讲解、答辩教学、文档编写、降重等。 ☑文末获取源码☑ 精彩专栏推荐⬇⬇⬇ Java项目 Py…

传输限速的方案那么多,却都没有这一个全面

在很多行业和领域&#xff0c;传输速度并不是无限制地越快越好&#xff0c;反而基于很多原因&#xff0c;在很多情况下&#xff0c;需要对传输的速度进行限制&#xff0c;原因如下&#xff1a; 带宽分配&#xff1a;在有限的网络资源下&#xff0c;对传输进行限速可以确保关键…

MIT-离散数学笔记

离散数学 PropositionEx 1:Ex 2:Ex 3:Ex 4:Ex 5:Ex 6:Ex 7:Ex 8: Proposition In mathematics, we have a mathematical proof is a verification of a proposition by a chain of logical deductions from a set of axioms. 在数学中&#xff0c;数学证明是通过一组公理的一系…

强化学习-alphazero 算法理论

一、算法简介 简单地说&#xff0c;AlphazeroMCTS SL(策略网络价值网络) Selfplay resnet。 其中MCTS指的是蒙特卡洛树搜索&#xff0c;主要用于记录所有访问过的棋盘状态的各种属性&#xff0c;包括该状态访问次数&#xff0c;对该状平均评价分数等。 SL指监督学习算法&…

PCDN技术如何提高数据传输的可靠性?

PCDN技术通过以下方式提高数据传输的可靠性: 1.负载均衡与故障转移: PCDN系统具备负载均衡的能力&#xff0c;可以根据节点的负载情况动态分配请求&#xff0c;避免单点故障和过载情况。此外&#xff0c;当某个节点发生故障时&#xff0c;PCDN可以迅速将流量转移到其他可用节…

OpenAI推出GPT-4o长输出版版本

&#x1f989; AI新闻 &#x1f680; OpenAI推出GPT-4o长输出版版本 摘要&#xff1a;OpenAI宣布正在测试每次请求可输出最多64K tokens的GPT-4o长输出版版本&#xff0c;目前仅Alpha测试参与者可使用。该版本推理成本较高&#xff0c;定价每百万tokens输入6美元&#xff0c;…

从微架构到向量化--CPU性能优化指北

引入 定位程序性能问题&#xff0c;相信大家都有很多很好的办法&#xff0c;比如用top/uptime观察负载和CPU使用率&#xff0c;用dstat/iostat观察io情况&#xff0c;ptrace/meminfo/vmstat观察内存、上下文切换和软硬中断等等&#xff0c;但是如果具体到CPU问题&#xff0c;我…

用于跟踪个人图书馆的BookLogr

什么是 BookLogr &#xff1f; BookLogr 是一款网络应用&#xff0c;旨在帮助您轻松管理个人图书馆。这项自托管服务可确保您完全控制数据&#xff0c;提供安全且私密的方式来跟踪您拥有、阅读或希望阅读的所有书籍。您也可以选择向公众自豪地展示您的图书馆&#xff0c;与您的…

申请流量卡不通过,这是什么原因呢,又该如何解决?

在申请流量卡时&#xff0c;有些人会出现被拒绝的情况&#xff0c;你知道这是怎么回事吗&#xff1f;申请流量卡被拒绝又该如何解决呢&#xff1f;下面这些问题都给你整理下了&#xff01; ​ 常见原因&#xff1a; 1.信息有误&#xff1a;收件人/办卡人&#xff1a;必须是同一…

How to specify the LangSmith project name for each Chain?

题意&#xff1a;如何为每个链指定LangSmith项目名称&#xff1f; 问题背景&#xff1a; According to the LangSmith documentation you need to set the LANGCHAIN_PROJECT environment variable to specify the project name in langsmith. 根据LangSmith的文档&#xff0…

Vmware ubuntu20.04 虚拟文件夹

目录 1.vmware 设置 2.ubuntu设置 1.vmware 设置 设置完成后我们开机 2.ubuntu设置 我们打开终端 输入命令 vmware-hgfsclient可以看到你当前的共享文件 然后我们输入以下命令&#xff0c;用于将共享文件夹挂载到虚拟机中 sudo vmhgfs-fuse .host:/ /mnt -o nonempty -o …

(24)(24.1) FPV和仿真的机载OSD(一)

文章目录 前言 1 参数 2 第二OSD 3 屏幕和屏幕切换 4 面板项目 5 呼号面板 6 用户可编程警告 7 使用SITL测试OSD 8 OSD面板列表 前言 使用 MAX7456 型芯片的板载操作系统和基于 MSP 的外部操作系统&#xff08;包括 DJI 护目镜和使用DisplayPort 的护目镜&#xff09…

【IEEE Fellow特邀报告,JPCS独立出版】第四届电子通信与计算机科学技术国际学术会议(ECCST 2024,9月20-22)

2024年第四届电子通信与计算机科学技术国际学术会议将于2024年9月20-22日在中国上海举行。 会议旨在为从电子与通信、网络、人工智能与计算机技术研究的专家学者、工程技术人员、技术研发人员提供一个共享科研成果和前沿技术&#xff0c;了解学术发展趋势&#xff0c;拓宽研究思…