C语言 之 理解指针(4)

news2024/9/20 6:12:03

文章目录

  • 1. 字符指针变量
  • 2. 数组指针变量
    • 2.1 对数组指针变量的理解
    • 2.2 数组指针变量的初始化
  • 3. 二维数组传参的本质
  • 4. 函数指针变量
    • 4.1 函数指针变量的创建
    • 4.2 函数指针变量的使用
  • 5. 函数指针数组

1. 字符指针变量

我们在前面使用的主要是整形指针变量,现在要学习的是字符指针变量。
一般使用:

int main()
{
 char ch = 'a';  //字符变量
 char *pc = &ch;  //字符指针变量
 *pc = 'b';
 return 0;
}

除了上面这种用法外,还有用于字符串。
如:

#include<stdio.h>
int main()
{
 const char* pstr = "hello world";
 printf("%s\n", pstr);
 return 0;
}

输出结果为:
在这里插入图片描述
代码 const char* pstr = "hello world"; 要注意:并不是把字符串hello world放入了字符指针变量pstr中,其本质是把字符串hello world的首个字符的地址放到了pstr中。
在这里插入图片描述
上面的代码如图所示,即把常量字符串的首字符h的地址存到了pstr

相关例题:

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int main()
{
	char str1[] = "hello world";
	char str2[] = "hello world";
	const char* str3 = "hello world";
	const char* str4 = "hello world";
	if (str1 == str2)
		printf("str1 and str2 are same\n");
	else
		printf("str1 and str2 are not same\n");

	if (str3 == str4)
		printf("str3 and str4 are same\n");
	else
		printf("str3 and str4 are not same\n");

	return 0;
}

输出结果为:
在这里插入图片描述
首先就像之前所说的,数组名是首元素的地址,str1和str2两个数组的内容虽然相同,但是使用相同的常量字符串去初始化不同的数组的时候就会开辟出不同的内存块,所以他们的地址是不同的。而对于str3和str4来说,它们是字符指针,它们指向的是同⼀个常量字符串。C语言中会把常量字符串存储到单独的⼀个内存区域,当⼏个指针指向同⼀个字符串的时候,实际上指向的是同⼀块内存。

2. 数组指针变量

2.1 对数组指针变量的理解

之前我们学习了指针数组,所以我们知道指针数组是用来存放指针的数组
那么数组指针变量是指针变量?还是数组?
答:指针变量

结合我们之前所学:
整形指针变量:int * p; 存放的是整形变量的地址,能够指向整形数据的指针。
字符指针变量:char * p; 存放的是字符变量的地址,能够指向字符数据的指针。
由此可得:数组指针变量应该是存放数组的地址,能够指向数组的指针变量。

数组指针变量:

int (*p)[10];

解释: p和*结合,说明了p是一个指针类型的变量,然后指针指向的是一个大小为10个整形的数组。所以
p是⼀个指针,指向⼀个数组,叫作数组指针

要注意的是:[]的优先级要⾼于*号,所以必须加上()来保证p先和 * 结合。
不能写成int *p[10];

2.2 数组指针变量的初始化

首先我们需要知道,数组指针变量是用来存放数组的地址的。
要想获得数组的地址,就得使用我们之前所学的操作符&
我们也知道,除了两个特殊情况,数组名就是首元素的地址,而这两个特殊情况中,&arr就是取整个数组的地址。

这里的&arr就是取了整个数组的地址,我们之前所学的指针存的都是一个地址,所以现在要想存一整个数组的地址,我们就得用到数组指针了。

int arr[10] = {0};
&arr;//得到的就是数组的地址

使用数组指针变量存放整个数组的地址:

 int(*p)[10] = &arr;

在这里插入图片描述

3. 二维数组传参的本质

在之前我们有⼀个⼆维数组的需要传参给⼀个函数的时候,我们可能是这样写的:

#include <stdio.h>
void test(int a[3][5], int r, int c)
{
	int i = 0;
	int j = 0;
	for (i = 0; i < r; i++)
	{
		for (j = 0; j < c; j++)
		{
			printf("%d ", a[i][j]);
		}
		printf("\n");
	}
}
int main()
{
	int arr[3][5] = { {1,2,3,4,5}, {2,3,4,5,6},{3,4,5,6,7} };
	test(arr, 3, 5);
	return 0;
}

这里的实参是二维数组,形参部分也写成了二维数组的形式,结合刚才所学,是否还有其它写法?

首先让我们再来回忆一下我们对数组的了解,假如有一个整形数组,那么它的每一个元素就是一个整形变量,那么二维数组呢?其实二维数组就可以看作是每个元素都是一维数组的数组,即二维数组的每个元素都是一维数组。那么一维数组的首元素就是第一个变量,二维数组的首元素就是二维数组的第一行,即第一个一维数组。
在这里插入图片描述

所以,根据数组名是数组首元素的地址这个规则,⼆维数组的数组名表示的就是第⼀行的地址,是⼀维数组的地址。根据上面的例子,第⼀行的⼀维数组的类型就是 int [5] ,所以第⼀行的地址的类
型就是数组指针类型 int(*)[5](注:对于数组,去掉数组名就是类型) 我们也知道,数组传参的本质是传首元素的地址,那就意味着⼆维数组传参本质上也是传递地址,传递的是第⼀行这个⼀维数组的地址,由于这个二维数组的首元素地址是一整个数组,那么形参也是可以写成指针形式的,即数组指针变量的形式。代码如下:

#include <stdio.h>
void test(int(*p)[5], int r, int c)
{
	int i = 0;
	int j = 0;
	for (i = 0; i < r; i++)
	{
		for (j = 0; j < c; j++)
		{
			printf("%d ", *(*(p + i) + j));
		}
		printf("\n");
	}
}
int main()
{
	int arr[3][5] = { {1,2,3,4,5}, {2,3,4,5,6},{3,4,5,6,7} };
	test(arr, 3, 5);
	return 0;
}

总结:二维数组传参,形参的部分可以写成数组,也可以写成指针形式。

4. 函数指针变量

4.1 函数指针变量的创建

经过我们前面的学习,通过类比
整形指针变量:int * p; 存放的是整形变量的地址,能够指向整形数据的指针。
字符指针变量:char * p; 存放的是字符变量的地址,能够指向字符数据的指针。
以及刚才的数组指针变量,所以我们就可以知道
函数指针变量是能够存放函数的地址,能够指向函数数据的指针啦。

所以,函数也是有地址的喔,我们可以来看看:

#include <stdio.h>
void test()
{
	printf("hehe\n");
}
int main()
{
	printf("test: %p\n", test);
	printf("&test: %p\n", &test);
	return 0;
}

输出结果为:
在这里插入图片描述
上面的例子中打印出来了地址,所以函数是有地址的,并且函数名就是函数的地址,当然也可以通过 &函数名的方式获得函数的地址

如果我们要将函数的地址存放起来,就得创建函数指针变量
函数指针变量的写法和数组指针变量的写法类似
如下:
例1:无参型

void test()
{
	printf("hehe\n");
}
void (*pf1)() = &test;
void (*pf2)() = test;

例2:带参型

int Add(int x, int y)
{
	return x + y;
}
int (*pf3)(int, int) = Add;
int (*pf3)(int x, int y) = &Add;  //x和y写上或者省略都是可以的

解析:
在这里插入图片描述

4.2 函数指针变量的使用

通过函数指针调⽤指针指向的函数

#include <stdio.h>
int Add(int x, int y)
{
	return x + y;
}
int main()
{
	int(*pf3)(int, int) = Add;

	printf("%d\n", (*pf3)(1, 2));
	printf("%d\n", pf3(10, 20));
	return 0;
}

输出结果:
在这里插入图片描述

5. 函数指针数组

我们前面已经学习了指针数组了,即所存放的每个元素是指针的数组。
如:

int *arr[10];
//数组的每个元素是int*

那么如果我们想要把每个函数的地址存放到数组中,这个数组就叫作函数指针数组
函数指针数组的定义:

int (*parr[3])();

parr 先和 [ ] 结合,说明 parr是数组,数组的内容是什么呢?是 int (*)() 类型的函数指针。

函数指针数组的使用 可以点击此处查看

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

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

相关文章

php--高级反序列化

&#x1f3bc;个人主页&#xff1a;金灰 &#x1f60e;作者简介:一名简单的大一学生;易编橙终身成长社群的嘉宾.✨ 专注网络空间安全服务,期待与您的交流分享~ 感谢您的点赞、关注、评论、收藏、是对我最大的认可和支持&#xff01;❤️ &#x1f34a;易编橙终身成长社群&#…

21 Python常用内置函数——zip()

zip() 函数用来把多个可迭代对象中的元素压缩到一起&#xff0c;返回一个可迭代的 zip 对象&#xff0c;其中每个元素都是包含原来的多个可迭代对象对应位置上元素的元组&#xff0c;最终结果中包含的元素个数取决于所有参数序列或可迭代对象中最短的那个。 可以这样理解这个函…

学习笔记(数据结构:队列)4

qt加库 队列&#xff1a; 队列是只允许在一段进行插入&#xff0c;而在另一端进行删除操作的线性表。 允许插入的称谓队尾&#xff0c;允许删除的一端队头。 顺序队列。 循环队列&#xff0c; 常用操作&#xff0c;入队&#xff0c;出队。 先进先出&#xff0c;FIFO 用&#x…

安装nfs和rpcbind设置linux服务器共享磁盘

1、安装nfs和rpcbind 1.1 检查服务器是否安装nfs和rpcbind&#xff0c;执行下命令&#xff0c;检查服务器是否安装过。 rpm -qa|grep nfs rpm -qa|grep rpcbind 说明服务器以安装了&#xff0c;如果没有就需要自己安装 2、安装nfs和rpcbind 将rpm安装包&#xff1a; libtirpc-…

【kubernetes】认识K8S基础理论

目录 1.背景 2.虚拟机、物理机与容器 3.K8S 基本概念 3.1 K8S 的特点 4.Kubernetes 集群架构与组件 4.1 核心组件 4.1.1 Master组件 4.1.2 配置存储中心 4.1.3 Node 组件 5.Kubernetes 核心概念 6.总结 1.背景 服务器经历了三次演变过程&#xff1a;物理机、虚拟机…

【北京迅为】《i.MX8MM嵌入式Linux开发指南》-第三篇 嵌入式Linux驱动开发篇-第五十八章 中断下文之tasklet

i.MX8MM处理器采用了先进的14LPCFinFET工艺&#xff0c;提供更快的速度和更高的电源效率;四核Cortex-A53&#xff0c;单核Cortex-M4&#xff0c;多达五个内核 &#xff0c;主频高达1.8GHz&#xff0c;2G DDR4内存、8G EMMC存储。千兆工业级以太网、MIPI-DSI、USB HOST、WIFI/BT…

跨越至智慧水利新时代:以科技创新为核心引擎,全面构建智能化水资源管理体系,显著提升水资源治理的智能化水平与高效治理能力,共筑可持续水生态未来

目录 一、智慧水利的概念与重要性 &#xff08;一&#xff09;智慧水利的概念 &#xff08;二&#xff09;智慧水利的重要性 二、智慧水利的关键技术 &#xff08;一&#xff09;物联网技术 &#xff08;二&#xff09;大数据技术 &#xff08;三&#xff09;云计算技术 …

Tekion 选择 ClickHouse Cloud 提升应用性能和指标监控

本文字数&#xff1a;4187&#xff1b;估计阅读时间&#xff1a;11 分钟 作者&#xff1a;ClickHouse team 本文在公众号【ClickHouseInc】首发 Tekion 由前 Tesla CIO Jay Vijayan 于 2016 年创立&#xff0c;利用大数据、人工智能和物联网等技术&#xff0c;为其汽车客户解决…

X00078-基于深度强化学习图神经网络的云工作流调度python

强化学习&#xff08;RL&#xff09;技术通过蒙特卡洛树搜索&#xff08;MCTS&#xff09;的加速&#xff0c;成功解决了多资源需求下的DAG问题&#xff0c;优化目标为缩短makespan。根据当前的计算资源和任务状态&#xff0c;MCTS算法被用来探索并选择最佳的动作&#xff0c;在…

【Linux】远程连接Linux虚拟机(MobaXterm)

【Linux】远程连接Linux虚拟机&#xff08;MobaXterm&#xff09; 零、原因 有时候我们在虚拟机中操作Linux不太方便&#xff0c;比如不能复制粘贴&#xff0c;不能传文件等等&#xff0c;我们在主机上使用远程连接软件远程连接Linux虚拟机后可以解决上面的问题。 壹、软件下…

快速搞定分布式RabbitMQ---RabbitMQ进阶与实战

本篇内容是本人精心整理&#xff1b;主要讲述RabbitMQ的核心特性&#xff1b;RabbitMQ的环境搭建与控制台的详解&#xff1b;RabbitMQ的核心API&#xff1b;RabbitMQ的高级特性;RabbitMQ集群的搭建&#xff1b;还会做RabbitMQ和Springboot的整合&#xff1b;内容会比较多&#…

The resource type Sheet does not implement java.lang.AutoCloseable

The resource type Sheet does not implement java.lang.AutoCloseable 修改一下 应该是【高版本JDK】切换集成到我这个项目【低版本 JDK 8】出错了

Ubuntu设置网络

进入网络配置文件夹 cd /etc/netplan 使用 vim 打开下的配置文件 打开后的配置 配置说明&#xff1a; network:# 网络配置部分ethernets:# 配置名为ens33的以太网接口ens33:addresses:# 为ens33接口分配IP地址192.168.220.30&#xff0c;子网掩码为24位- 192.168.220.30/24n…

【MySQL】:表操作语法大全

表内容的操作 增删改查 CRUD (create、retrieve、update、delete) 新增 基本语法 语法为&#xff1a; insert into 表名 values (值&#xff0c;值&#xff0c;值...);这里的列数和类型&#xff0c;要和表结构匹配插入中文的话&#xff0c;要确保数据库创建的时候要设置字…

Python 高阶语法

前言&#xff1a; 我们通过上篇文章学习了Python的基础语法&#xff0c;接下来我们来学习Python的高阶语法 1.初识对象 在Python中我们可以做到和生活中那样&#xff0c;设计表格、生产表格、填写表格的组织形式的 面向对象包含 3 大主要特性&#xff1a;  封装  继承 …

NLP基础知识2【各种大模型的注意力】

注意力 传统Attention存在的问题优化方向变体有哪些现在的主要变体集中在KVMulti-Query AttentionGrouped-query AttentionFlashAttention 传统Attention存在的问题 上下文约束速度慢&#xff0c;显存占用大&#xff08;因为注意力考虑整体信息&#xff0c;所以每一个位置都要…

mysql之触发器的使用

cr一&#xff1a;创建goods表和orders表&#xff1b; mysql> use mydb16_tirgeer Database changed mysql> create table goods(-> gid char(8) primary key,-> name varchar(10),-> price decimal(8,2),->-> num int); Query OK, 0 rows affected (0.0…

18 Python常用内置函数——排序与逆序

sorted() 对列表、元组、字典、集合或其他可迭代对象进行排序并返回新列表&#xff0c;reversed() 对可迭代对象&#xff08;生成器对象和具有惰性求值特性的 zip、map、filter、enumerate 等类似对象除外&#xff09;进行翻转&#xff08;首尾交换&#xff09;并返回可迭代的 …

《GPT-4o mini:开启开发与创新的新纪元》

在科技发展的快速进程中&#xff0c;OpenAI 推出的 GPT-4o mini 模型如同一阵春风&#xff0c;给开发者们带来了新的希望和机遇。它以其卓越的性能和极具吸引力的价格&#xff0c;成为了行业内热议的焦点。 当我首次听闻 GPT-4o mini 的消息时&#xff0c;内心充满了好奇与期待…

深度学习目标检测入门实战

深度学习目标检测入门实战 一、什么是目标检测二、目标检测常用的数据集&#xff08;开源&#xff09;&#xff08;一&#xff09;VOC数据集&#xff08;1&#xff09;背景知识&#xff08;2&#xff09;数据集的下载&#xff08;3&#xff09;VOC2007 数据集的标注&#xff08…