C语言-指针进阶(9.1)

news2024/12/24 9:21:07

目录

思维导图:

1. 字符指针

2. 指针数组

3. 数组指针

3.1 数组指针的定义

3.2 &数组名VS数组名

3.3 数组指针的使用

4. 数组传参和指针传参

4.1 一维数组传参

4.2 二维数组传参

4.3 一级指针传参

4.4 二级指针传参

写在最后


思维导图:

 

1. 字符指针

顾名思义,字符指针就是存放字符的指针

char* 就是字符指针的类型。

例:

#include <stdio.h>

int main()
{
	char ch = 'a';//字符
	char* p = &ch;//p就是字符指针
	*p = 'b';
	printf("%c", *p);
	return 0;
}

输出:

输出:b

例2:

#include <stdio.h>

int main()
{
	char arr[] = "abcdef";
	char* pa = arr;//字符指针存放字符串首字符地址
	printf("%s\n", pa);
	return 0;
}

输出:

输出:abcdef

例3:

有这样一道面试题:

#include <stdio.h>

int main()
{
	//str1和str2是开辟一块内存空间存放的字符串
	//所以他们分别在不同的内存地址
	char str1[] = "hello bit.";
	char str2[] = "hello bit.";

	//字符串"hello bit."是常量字符串
	//C语言会将常量字符串单独存储到一个区域
	const char* str3 = "hello bit.";
	const char* str4 = "hello bit.";

	//所以str1和str2在不同地址存放
	//而str3和str4位于同一个地址
	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 and str2 are not same
str3 and str4 are same

2. 指针数组

指针数组是什么?

是数组,每个元素是指针的数组。

例:

	int* arr1[10];//整形指针的数组
	char* arr2[5];//字符指针的数组
	int** arr3[15];//二级整形指针的数组

3. 数组指针

3.1 数组指针的定义

那数组指针又是什么?

是指针,指向数组的指针。

那我们该怎么更好判断数组与指针的关系呢?

可以看主语是什么,例如:红红的苹果是 苹果。

那么,数组指针自然是 指针,指针数组自然是 数组。

例:

	int arr[10];
	int(*p)[10] = &arr;//注意看:*p与()结合,这是一个指针,指针数组
	                   //&arr 取出的是整个arr数组的地址

3.2 &数组名VS数组名

我们直接上代码:

#include <stdio.h>

int main()
{
	int arr[10] = { 0 };

	printf("%p\n", arr);
	printf("%p\n", &arr);

	return 0;
}

输出:

输出:
00CFF88C
00CFF88C

结果发现打印出来的都是首元素地址

那 arr 与 &arr 究竟有什么区别呢?

#include <stdio.h>

int main()
{
	int arr[10] = { 0 };

	printf("arr = %p\n", arr);
	printf("&arr= %p\n", &arr);

	printf("arr+1 = %p\n", arr + 1);//跳过一个元素的地址
	printf("&arr+1= %p\n", &arr + 1);//跳过一整个数组的地址

	return 0;
}

输出:

输出:
arr = 00AFFC7C
&arr= 00AFFC7C
arr+1 = 00AFFC80
&arr+1= 00AFFCA4

所以在本质上,

arr是首元素的值,

而&arr是整个数组的地址。

3.3 数组指针的使用

我们可以用于接收一个二维数组的传参:

例:

#include <stdio.h>

void print_arr1(int arr[3][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 ", arr[i][j]);
		}	
		printf("\n");
	}
}

void print_arr2(int(*arr)[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 ", arr[i][j]);
		}
		printf("\n");
	}
}

int main()
{
	int arr[3][5] = { 1,2,3,4,5,6,7,8,9,10 };

	print_arr1(arr, 3, 5);//二维数组的数组名其实表示的是
	                      //二维数组第一行的地址,
	print_arr2(arr, 3, 5);//也就是一个数组的地址

	return 0;
}

输出:

输出:
1 2 3 4 5
6 7 8 9 10
0 0 0 0 0
1 2 3 4 5
6 7 8 9 10
0 0 0 0 0

4. 数组传参和指针传参

4.1 一维数组传参

例:

#include <stdio.h>

//arr
void test(int arr[])//可以接收,数组元素个数不是必要的
{}

void test(int arr[10])//可以接收,与原数组一模一样便于观察
{}

void test(int* arr)//可以接收,arr是数组首元素地址,可以用指针接收
{}

//***********************//

//arr2
void test2(int* arr[20])//可以接收,与原数组一模一样便于观察(当然,形参名可以自定义)
{}

void test2(int** arr)//可以接收,int*是数组元素类型,arr是数组首元素地址,用指针接收
{}

int main()
{
	int arr[10] = { 0 };
	int* arr2[20] = { 0 };

	test(arr);

	test2(arr2);

	return 0;
}

4.2 二维数组传参

例:

void test(int arr[3][5])//可以接收,与原数组一模一样便于观察
{}

void test(int arr[][])//不能接收
{}

void test(int arr[][5])//可以接收,二维数组传参,接收时必须知道一行有多少元素
{}                                                   //但是可以不知道有多少列

void test(int* arr)//不能接收,二维数组传来的是第一行的地址,不能用一个首元素地址接收
{}

void test(int* arr[5])//不能接收,这是个指针数组,自然不能接收二维数组
{}

void test(int(*arr)[5])//可以接收,用数组指针接收二维数组第一行的数组
{}

void test(int** arr)//不能接收,这是一个指针数组的首元素地址,不能接收二维数组
{}

int main()
{
	int arr[3][5] = { 0 };

	test(arr);

	return 0;
}

4.3 一级指针传参

例:

#include <stdio.h>

void print(int* p, int sz)//用指针接收
{
	int i = 0;
	for (i = 0; i < sz; i++)
	{
		printf("%d ", *(p + i));//*(p + i)也可以写成 p[i] 
	}
}
int main()
{
	int arr[10] = { 1,2,3,4,5,6,7,8,9 };
	int* p = arr;
	int sz = sizeof(arr) / sizeof(arr[0]);

	print(p, sz);//将指针传参

	return 0;
}

输出:

输出:
1 2 3 4 5 6 7 8 9 0

4.4 二级指针传参

例:

#include <stdio.h>

void test(int** ptr)//二级指针接收
{
	printf("num = %d\n", **ptr);
}

int main()
{
	int n = 10;
	int* p = &n;//一级指针
	int** pp = &p;//二级指针

	test(pp);
	test(&p);//这两个函数都是传的二级指针
	return 0;
}

输出:

输出:
num = 10
num = 10

写在最后:

以上就是本篇文章的内容了,感谢你的阅读。

如果喜欢本文的话,欢迎点赞和评论,写下你的见解。

如果想和我一起学习编程,不妨点个关注,我们一起学习,一同成长。

之后我还会输出更多高质量内容,欢迎收看。

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

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

相关文章

年底赶进度,如何将开发风险降到最低?

1、科学规划风险策略和控制流程 针对开发流程各环节中可能存在的风险&#xff0c;项目经理需要进行项目风险分析&#xff0c;并制定符合项目特点的风险评估和监督机制&#xff0c;实行岗位负责制&#xff0c;提前制定好控制策略&#xff0c;将开发风险降到最低。 如何将开发风险…

分布式基础篇2——分布式组件

一、SpringCloud Alibaba1、简介2、为什么使用3、版本选择4、依赖选择二、SpringCloud Alibaba 组件1、Nacos作为注册中心2、OpenFeign3、Nacos作为配置中心namespaceData IDGroup同时加载多个配置文件三、Spring Cloud1、GateWay简介三大核心部分网关的使用视频来源: 【Java项…

Ansible剧本流程控制

handlers触发器 notify&#xff1a;监控上面的模块执行是否发生变化 chufa&#xff1a;自定义的任务名称&#xff0c;自动去handlers里面匹配相对应的任务名称执行动作 下方是copy了/data/copy/下的文件到server2组里的主机/data/monster/handlers/下&#xff0c;notify监控发…

如何下载指定版本的xcode

如何下载指定版本的xcode一、安装最新版本xcode二、下载指定版本xcode一、安装最新版本xcode 从苹果商店中获取并安装即可。 但是安装最新版有个风险&#xff0c;就是它有系统版本的要求&#xff0c;比如这里要求macOS版本最低是12.5 如果版本不够的话&#xff0c;可以升级系统…

【蓝桥杯基础题】2020年省赛填空题—既约分数

&#x1f451;专栏内容&#xff1a;蓝桥杯刷题⛪个人主页&#xff1a;子夜的星的主页&#x1f495;座右铭&#xff1a;前路未远&#xff0c;步履不停 目录一、题目背景二、题目描述三、题目分析1.求最大公约数①辗转相减法②穷举法③辗转相除法④辗转相除法&#xff08;递归&am…

LVGL之学习篇(一)

LVGL之学习篇(一) 学习目的 LVGL简介 LVGL本身是一个图形库&#xff0c;前身是litterVGL。其作者是来自匈牙利的Gabor Kiss-Vamosikisvegabor&#xff0c;LVGL用C语音编写&#xff0c;以实现最大的兼容性(与C兼容)&#xff0c;模拟器可在没有嵌入式硬件的PC上启动嵌入式GUI设计…

MATLAB实验三

实验三 &#xff08;实验报告中附上每题的主要程序和结果&#xff09; 1、在命令行窗口中分别输入下列命令&#xff0c;对应输出结果是 A&#xff0e;命令x[-2:2] B&#xff0e;命令xzeros(1,2);x>0 C&#xff0e;命令ydiag(eye(3),1) D&#xff0e;命令[-2:2]30*eye(…

内存分页机制

文章目录内存分页的原因一级页表分页机制的原理一级页表二级页表二级页表概述地址转换启动分页机制内存分页的原因 在还未出现内存分页机制之前&#xff0c;我们都内存分段机制下工作。 但是&#xff0c;这样会有个问题。来看个下方的例子。 进程在分段机制下运行 下图&…

【学习记录】ORBSLAM2均匀化策略源码解析

在ORBSLAM中&#xff0c;为了保证特征的均匀分布使用了均匀化的策略&#xff0c;最近在尝试扩展一下均匀化的内容&#xff0c;所以仔细看了一下ORBSLAM源码里面这部分的内容&#xff0c;之前看源码的时候没有展开仔细看这一部分的代码&#xff0c;这里补充记录一下&#xff0c;…

未来SSD的接口趋势是什么?

针对SSD接口标准&#xff0c;目前业内有两大组织&#xff1a;PCI-SIG&#xff1a;这个就是定义pcie协议标准的那个组织&#xff0c;我们常见的传统接口M.2, U.2, 2.5英寸的接口都归这个组织定义规范。M.2&#xff0c;U.2起源与客户端&#xff0c;也是企业级当前最常用的接口形式…

elasticdump迁移ES数据详解

文章目录elasticdump 简介1.elasticdump导入ES数据到本地json文件2、将本地数据导入es中3、将es导入另一个es4 .其他参数使用--searchBody使用--searchBody 向本机ES导数据使用--typeanalyzer导出分析器elasticdump 简介 elasticdump是一个能够将es的数据快速导入、导出、迁移…

最新最全-中文生物医学命名实体识别最新研究论文、资源、数据集、性能整理分享

本资源旨在跟踪中文生物医学自然语言处理的进展&#xff0c;收集整理相关的论文列表和展示现存方法性能。内容整理自网络&#xff0c;源地址&#xff1a;https://github.com/lingluodlut/Chinese-BioNLP中文电子病历命名实体识别中文电子病历命名实体识别&#xff08;Chinese C…

《操作系统-真象还原》阅读总结/遗憾离场/加倍努力 出人头地

文章目录关于我又被老天算计奇奇怪怪的 BUG调试 BUG 的心理历程最后两天通宵调试程序的宵夜阅读建议本书所有笔记最后关于我又被老天算计 从 2022-09-14 读这本书&#xff0c;原计划是 2022-12-15 之前完成的&#xff0c;我自信能完成&#xff0c;因为11月下旬我已经开始阅读第…

【Linux】初识进程

文章目录进程控制块的引入初识进程控制块(PCB - Process Control Block)什么是PCBLinux下的PCB初见进程ps指令查看进程kill指令挂掉进程通过系统调用接口得到进程的ID(进程标识符)从根目录下的proc文件查看进程通过fork函数创建子进程进程控制块的引入 首先&#xff0c;听到进…

事故复盘 | 对不同的ID更新操作竟然也引发死锁?

对不同的ID更新操作竟然也引发死锁&#xff1f; 文章目录对不同的ID更新操作竟然也引发死锁&#xff1f;背景分析初步分析 - 怀疑程序并发问题进一步分析 - 怀疑主键缺失行级锁失效再进一步分析 - 是否存在死锁条件解决方案复盘附录示例的死锁日志常用故障排查 SQL参考链接背景…

webassembly学习

webassemblywebassembly学习基本理论webassembly介绍wasm介绍基本信息wasm会替换javascript么ASM.js&#xff08;wasm的前身&#xff09;将 WebAssembly 作为编程语言的一种尝试wasm应用场景wasm运行原理周边生态WASI 操作系统接口wasi介绍wasmwasi&#xff08;服务端&#xff…

平台总线式驱动开发——基本框架

1. 总线、设备和驱动 硬编码式的驱动开发带来的问题&#xff1a; 垃圾代码太多结构不清晰一些统一设备功能难以支持开发效率低下 1.1 初期解决思路&#xff1a;设备与驱动分离 struct device来表示一个具体设备&#xff0c;主要提供具体设备相关的资源&#xff08;如寄存器地…

ES为什么要移除types类型

文章目录elasticsearch&#xff08;集群&#xff09;中可以包含多个索引index&#xff08;数据库&#xff09; ,每个索引中可以包含多个类型types&#xff08;表&#xff09; ,每个类型下又包含多个文档Document&#xff08;行&#xff09; ,每个文档中又包含多个字段Field&…

姿态估计评价指标

PCK 正确估计出关键点的百分比 &#xff08;Percentage of Correct Keypoints&#xff09;&#xff0c;现在已基本不用。 PCKik∑iδ(did≤Tk)∑i1PCK_i^k\frac{\sum_i\delta(\frac{d_i}{d}\leq T_k)}{\sum_i1} PCKik​∑i​1∑i​δ(ddi​​≤Tk​)​ 检测出的关键点与其对应…

1 机器学习之线性回归

学习笔记自&#xff0c;慕课网 《Python3 入门人工智能》 https://coding.imooc.com/lesson/418.html#mid33109 麻雀虽小&#xff0c;五脏俱全 1.1 回归分析 1.2 线性回归问题求解 1.3 寻找最合适的 a、b&#xff0c;引入损失函数的概念 尽可能使损失函数最小即找到了最合适的…