【C语言_指针(3)_复习篇】

news2024/11/25 0:21:53

目录

一、字符指针变量

二、数组指针变量

三、二维数组传参的本质

四、函数指针变量

五、 typedef关键字

六、函数指针数组

七、转移表(函数指针数组的实践)


一、字符指针变量

1. 字符指针变量是指里面存放的是字符变量地址的指针变量,对这个字符指针变量解引用就可以找到其所指向的字符变量。

2. 拓展用法:字符指针变量可以存放常量字符串的首地址。

    解释说明:常量字符串与其他常量相比,编译器有给它提供内存空间存储常量字符串中的每个字符,存放这个常量字符串的地址是固定的,如图1的代码的验证,整个常量字符串表示常量字符串首元素的地址,我们可以将它的地址存放在字符指针中,并通过解引用和指针的偏移找到这个常量字符串中的每个字符,但我们是没有权限通过对指针解引用去修改常量字符串中元素的数据的

3. 注意理解:当我们想要访问一个数组每个元素时,可以利用数组首元素地址arr或存有数组首元素地址的指针p+ [i],表示利用数组首元素地址偏移并解引用找到地址所指向的变量,arr[i] == p[i],或写成 i[arr]==i[arr];也可以写成这种形式 *(arr+i)=*(p+i) 。

int main()
{
     char str1[] = "hello bit.";
     char str2[] = "hello bit.";
     const char *str3 = "hello bit.";//常量字符串的存储地址不会变化
     const char *str4 = "hello bit.";
     //
     if(str1 == str2)
         printf("str1 and str2 are same\n");
     else
         printf("str1 and str2 are not same\n");//打印not same
     //
     if(str3 == str4)
         printf("str3 and str4 are same\n");//打印same
     else
         printf("str3 and str4 are not same\n");
     return 0;
}
int main()
{
	//字符指针变量的普通应用
	char arr = 'B';
	char* p = &arr;
	*p = 'W';
	printf("%c\n", arr);

	//字符指针变量存放常量字符串
	char* ptr = "ABCDE";
	printf("%c\n", *ptr);//A
	printf("%c\n", *(ptr + 1));//B
	printf("%c\n", ptr[2]);//C      //数组首元素地址加[]和下标表示地址偏移并解引用
	printf("%c\n", "ABCDE"[2]);//C

	return 0;
}

二、数组指针变量

1. 数组指针变量是指里面存放的是数组地址的指针变量(不是数组首元素的地址),对数组指针变量解引用就可以找到其所指向的整个数组,注意这里相当于得到了所指向数组的变量名。

2. 数组指针变量初始化就是将一个数组的地址存入数组指针变量即可,或则置NULL

3.数组指针变量类型的理解:以int (*p)[10]为例,(*)表示p是一个指针变量,[10]表示这个指针变量所指向的对象是一个有10个元素的一维数组,int表示所指向的一位数组中的每个元素的类型是int类型。(注意区分指针数组和数组指针变量)

4. 数组指针一般不会在一维数组里使用,要使用也会在二维及以上数组中使用,通常用于二维数组传参

//数组指针变量的创建
int mian()
{
	int n1 = 10;
	int* p1 = &n1;//整型指针变量

	char n2 = 'a';
	char* p2 = &n2;//字符指针变量

	float n3 = 12.8f;
	float* p3 = &n3;//单精度浮点型指针变量

	int arr[10] = { 0 };
	int(*p4)[10] = &arr;//数组指针变量
                        //指针变量p4的类型是int (*)[10]
	return 0;
}
//使用数组指针变量访问数组中的每一个元素(一般不会采取这样的方式访问)
int main()
{
	int arr[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
	int sz = sizeof(arr) / sizeof(arr[0]);
	int(*p)[10] = &arr;//p是数组指针变量
	int i = 0;
    //如果想通过数组指针访问数组中的所有元素:
	for (i = 0; i < sz; i++)
	{
		printf("%d ", (*p)[i]);//*p可以找到p所指向的整个数组arr,
							   //整个数组的数组名又是数组首元素的地址
							   //换句话说对整个数组的地址同时&和*等同于无效操作
							   //对数组首元素地址进行地址偏移和解引用即可找到数组中的所有元素
	}
	return 0;
}

三、二维数组传参的本质

1. ⼆维数组传参传递的是二维数组第⼀⾏⼀维数组的地址

2. 二维数组的行和列的大小和一维数组一样只能在自己被创建的函数中求。

3. 二维数组传参,形参的部分也有两种写法:① 直接写成二维数组的形式,② 也可以写成数组指针的形式,但形参的本质都是二维数组第⼀⾏⼀维数组的地址,只是不同写法而已。

4. 注意理解:二维数组传参也属于传址调用

//使用自定义函数打印二维数组中每一个元素
void Print(int(*p)[5], int row, int col)
{
	int i = 0;
	for (i = 0; i < row; i++)
	{
		int j = 0;
		for (j = 0; j < col; j++)
		{
			printf("%d ", *(*(p + i) + j));//==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 } };
	Print(arr, 3, 5);//数组名是数组首元素的地址,这里的二维数组,首元素是一个一维数组
					 //所以二维数组传参其实是传的数组指针变量
	return 0;
}

四、函数指针变量

1. 函数指针变量是指里面存放的是函数地址的指针变量,对函数指针变量解引用就可以找到其所指向的函数,并且我们可以通过传递实参达到调用这个函数的效果。

2. Add==&Add(和数组不同,函数名和&地址函数名都是表示这个函数的地址

3. 函数指针变量类型的理解,以int (*p) (int x, int y)为例,(*)表示p是一个指针变量,(intx,inty)表示指针变量p所指向的函数的参数有几个,分别是什么类型的,int表示指针变量所指向的函数的返回类型是int类型。

4. 函数指针变量的使用:可以写成(*指针)+(),表示通过解引用指针变量找到函数,并对函数进行传参;也可以直接指针+(),因为函数调用时()左边的就时函数的地址。

int Add(int x, int y)
{
	return x + y;
}

int main()
{
	int a = 10, b = 20;
	int (*p)(int x, int y) = Add;//x和y可以不写int (*p)(int, int)

	int ret1 = p(a, b);
	printf("%d\n", ret1);//30

	int ret2 = (*p)(a, b);
	printf("%d\n", ret2);//30
	return 0;
}

五、 typedef关键字

1. typedef 是⽤来类型重命名的,可以将复杂的类型简单化。

typedef unsigned int uint;
//将unsigned int 重命名为uint
typedef int* ptr_t;
//将指针类型int* 重命名维ptr_t

//对数组指针和函数指针重命名
typedef int(*parr_t)[5]; //新的类型名必须在*的右边
typedef void(*pfun_t)(int);//新的类型名必须在*的右边

六、函数指针数组

1. 函数指针数组是存放函数指针的数组函数指针数组里的元素全都是函数指针

2. 函数指针数组的类型由数组中每个元素的类型决定,但写法比较独特,具体见下方代码。

    即把函数指针类型中写指针名称的地方写成函数指针数组名和数组大小,去掉数组名称剩下的就是函数指针数组类型。

int Add(int x, int y)
{
	//...
	return x + y;
}

int Sub(int x, int y)
{
	//...
	return x - y;
}

int Mul(int x, int y)
{
	//...
	return x * y;
}

int main()
{
	int (*arr[3])(int, int) = { Add, Sub, Mul };//函数指针数组
                                                //arr是数组名,[3]表示数组大小
    //int ret = (arr+1)(2, 3);//err
	//int ret = (*(arr + 1))(2, 3);
	int ret = arr[1](2, 3);//下标直接访问
	printf("%d\n", ret);
	return 0;
}

七、转移表(函数指针数组的实践)

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

int sub(int a, int b)
{
	return a - b;
}

int mul(int a, int b)
{
	return a * b;
}

int div(int a, int b)
{
	return a / b;
}

int main()
{
	int x, y;
	int input = 1;
	int ret = 0;
	int(*p[5])(int x, int y) = { 0, add, sub, mul, div }; //转移表
	do
	{
		printf("*************************\n");
		printf(" 1:add 2:sub \n");
		printf(" 3:mul 4:div \n");
		printf(" 0:exit \n");
		printf("*************************\n");
		printf("请选择:");
		scanf("%d", &input);
		if ((input <= 4 && input >= 1))
		{
			printf("输⼊操作数:");
			scanf("%d %d", &x, &y);
			ret = p[input](x, y);
			printf("ret = %d\n", ret);
		}
		else if (input == 0)
		{
			printf("退出计算器\n");
		}
		else
		{
			printf("输⼊有误\n");
		}
	} while (input);
	return 0;
}

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

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

相关文章

深入挖掘C语言之——联合

目录 联合的定义 联合的特点 联合的应用场景 在C语言中&#xff0c;联合&#xff08;Union&#xff09;是一种特殊的数据结构&#xff0c;它允许在同一内存地址存储不同类型的数据。与结构体&#xff08;Struct&#xff09;不同的是&#xff0c;联合中的所有成员共享同一块内…

Zookeeper搭建

目录 前言 初了解Zookeeper 搭建 准备 配置Zookeeper 前言 今天来介绍Zookeeper的搭建&#xff0c;其实Zookeeper的搭建很简单&#xff0c;但是为什么还要单独整一节呢&#xff0c;这就不得不先了解Zookeeper有什么功能了&#xff01;而且现在很火的框架也离不开Zookeepe…

有来团队后台项目-解析5

一、 husky 安装 pnpm install -D husky生成husky 配置文件 如果文件中有.git文件&#xff0c;那么直接执行 npx husky-init如果没有&#xff0c;那么先执行git init 结果&#xff1a; PS F:\company_project\demo\youlahoutaijiexi\vite-project> git init Initializ…

2.Datax数据同步之Windows下,mysql和sqlserver之间的自定义sql文数据同步

目录 前言步骤操作大纲步骤明细mysql 至 sqlServersqlServer 至 mysql执行同步语句中报 前言 上一篇文章实现了不同的mysql数据库之间的数据同步&#xff0c;在此基础上本篇将实现mysql和sqlserver之间的自定义sql文数据同步 准备工作&#xff1a; JDK(1.8以上&#xff0c;推…

数据结构 day2

1:思维导图 2&#xff1a;计算结构体大小 3&#xff1a;大小端存储 &#xff08;1&#xff09;&#xff1a;数据溢出 1 #include <stdio.h>2 #include <string.h>3 #include <stdlib.h>4 int main(int argc, const char *argv[])5 {6 short a 0x1234;…

JMeter使用记录

文章目录 概述从0创建一个测试场景线程组配置元件CSV Data Set ConfigHTTP信息头管理器HTTP Cookie管理器HTTP请求默认值 逻辑控制器简单控制器IF控制器循环控制器while控制器 取样器HTTP取样 前置/后置处理器BeanShell处理器JSR223处理器 监听器查看结果树聚合报告汇总报告 概…

保护数字前沿:有效的威胁暴露管理

人工智能技术正在从根本上改变网络安全领域的方向。仅 2023 年&#xff0c;全球企业预计将在人工智能上花费 1027.8 亿美元&#xff0c;以阻止网络安全威胁。 人工智能 (AI)在增强网络安全措施方面发挥着关键作用&#xff0c;因为它能够快速分析大量数据并识别可能表明潜在威胁…

windows系统图标变白设置

我们在使用系统的时候&#xff0c;通常会在桌面创建图标&#xff0c;有时候桌面图标过多&#xff0c;整理图标放在新建文件夹的时候&#xff0c;图标变白&#xff0c;通常情况下都是缓存问题&#xff0c;这里也是删除缓存解决演示系统&#xff1a;windows11 1显示图标缓存目录 …

力扣--深度优先算法/回溯算法47.全排列 Ⅱ

思路分析&#xff1a; 使用DFS算法进行全排列&#xff0c;递归地尝试每个可能的排列方式。使用 path 向量保存当前正在生成的排列&#xff0c;当其大小达到输入数组的大小时&#xff0c;将其加入结果集。使用 numvisited 向量标记每个数字是否已经被访问过&#xff0c;以确保每…

五 超级数据查看器 讲解稿 列表功能2

五 超级数据查看器 讲解稿 列表功能2 点击此处 以新页面 打开B站 播放教学视频 点此下载 百度手机助手 下载地址4 讲解稿全文&#xff1a; 大家好&#xff0c;今天我们讲解一下&#xff0c;超级数据查看器列表界面&#xff0c;分为1-2两集。这是第二集 继续讲解弹出式菜单…

基于YOLOv8/YOLOv7/YOLOv6/YOLOv5的远距离停车位检测系统(深度学习代码+UI界面+训练数据集)

摘要&#xff1a;开发远距离停车位检测系统对于提高停车效率具有关键作用。本篇博客详细介绍了如何运用深度学习构建一个远距离停车位检测系统&#xff0c;并提供了完整的实现代码。该系统基于强大的YOLOv8算法&#xff0c;并对比了YOLOv7、YOLOv6、YOLOv5&#xff0c;展示了不…

极简云商业版 开源源码

简化版的云商业源码已经以开源形式发布了&#xff0c;现在可以解绑卡密和查询卡密。总体而言&#xff0c;这个版本已经相当完善了。在对接示例网盘中有一个用户注册的例子&#xff0c;需要配置一个邮箱。您可以在网页上启用QQ邮箱的标准版SMTP&#xff0c;并生成一个授权码。 …

【多用途】Fruits-360:包含水果和蔬菜的图像数据集

一、介绍 该数据集包含水果和蔬菜的高质量图像数据集。 包括以下水果和蔬菜&#xff1a; Apples (different varieties: Crimson Snow, Golden, Golden-Red, Granny Smith, Pink Lady, Red, Red Delicious), Apricot, Avocado, Avocado ripe, Banana (Yellow, Red, Lady Fin…

关于c++的protected关键字

关于c的protected关键字 分类引言例子1&#xff09;错误的demo2&#xff09;改正的demo protected在c中的含义与作用 分类 c基础知识 引言 做了很业务&#xff0c;c基础知识却忘了很多&#xff0c;今天看了一个例子&#xff0c;唤醒了我关于c三大特性之一----封装&#xff0…

一文看明白Transformer微调过程中嵌入向量的变化

TL&#xff1b;DR 微调在图像分类中显著影响嵌入向量。微调前的嵌入向量提供通用性表征&#xff0c;而微调后的嵌入向量捕获任务特定的特征。这种区别可能导致在异常检测和其他任务中的不同结果。微调前和微调后的嵌入向量各有其独特优势&#xff0c;应结合使用以实现图像分类…

【MySQL 系列】MySQL 语句篇_DDL 语句

DDL&#xff08; Data Definition Language&#xff0c;数据定义语言&#xff09;用在定义或改变表的结构数据类型、表之间的链接和约束等初始化工作上。常用的语句关键字包括 CREATE、 DROP、 ALTER 等。 文章目录 1、MySQL 中的 DQL 语句2、MySQL 中库表的 DQL 语句详解2.1、…

[leetcode~dfs]1261. 在受污染的二叉树中查找元素

给出一个满足下述规则的二叉树&#xff1a; root.val 0 如果 treeNode.val x 且 treeNode.left ! null&#xff0c;那么 treeNode.left.val 2 * x 1 如果 treeNode.val x 且 treeNode.right ! null&#xff0c;那么 treeNode.right.val 2 * x 2 现在这个二叉树受到「污…

LeetCode刷题---即时食物配送 II

LeetCode题解 解题思路: 1.首先先求出每个用户首次订单表&#xff0c;将其命名为表t &#xff08;select customer_id,min(order_date) as order_datefrom Deliverygroup by customer_id&#xff09;as t2.与原表连接&#xff0c;求出在用户首次订单表中即时订单的数量的总和…

遥感云计算的一个拐点

GeoForge&#xff0c;一个值得关注的遥感大数据应用 简介 GeoForge是由Ageospatial公司开发的一个基于大语言模型(GeoLLMs)的地理空间分析平台。GeoForg的目的是使每个人都可以轻松进行地图绘制和地理空间分析&#xff0c;无论您是外行还是专家。 Geo for ChatGPT 作者团队已…

多模态大模型Claude 3正式接入集简云与语聚!对标GPT-4且支持中文

自OpenAI发布GPT-4以来&#xff0c;引发了业务模式与应用使用的巨大变革&#xff0c;掀起了各大企业对于多模态大模型的研究热潮。3月初&#xff0c;AnthropicClaude在官网正式发布Claude 3系列多模态大模型&#xff0c;据了解&#xff0c;该模型在多个维度上超越了GPT-4&#…