c语言进阶部分详解(指针进阶1)

news2024/11/27 14:49:27

大家好!指针的初阶内容我已经写好,可移步至我的文章:c语言进阶部分详解(指针初阶)_总之就是非常唔姆的博客-CSDN博客

 基本内容我便不再赘述,直接带大家进入进阶内容:


目录

一.字符指针

1.讲解 

2.例题 

二.指针数组 

1.讲解 

2.练习

三.数组指针

1.数组指针的定义 

2.数组指针与指针数组在语法上的对比 

3.&数组名VS数组名 

4.数组指针的使用 

 四.数组参数、指针参数

1.一维数组传参 

 2.二维数组传参

 3.一级指针传参

4.二级指针传参 

思考:当函数的参数为二级指针的时候,可以接收什么参数


一.字符指针

1.讲解 

在指针的类型中我们知道有一种指针类型为字符指针 char* ; 

其一般的使用场景为:这样

#include<stdio.h>
int main()
{
	char a = 'z';
	char* pa = &a;
	return 0;
}

 还有这样:

int main()
{
	char* arr = "hello";
	printf("%s", arr);
	return 0;
}

 针对char* arr = "hello";这个语句,特别容易让各位以为是把字符串 hello放到字符指针 arr 里了,但是本质是把字符串 hello首字符的地址放到了arr中

2.例题 

下面来看一个例题加深理解:大家可以先思考一下再进行答案的比对

int main()
{
	char str1[] = "hello";
	char str2[] = "hello";
	const char* str3 = "hello";
	const char* str4 = "hello";
	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;
}

答案:

 各位对了吗?

  • 使用"=="运算符比较指针时,实际上比较的是指针所指向的地址是否相同,而不是比较字符串的内容是否相同
  • 这里str3和str4指向的是一个同一个常量字符串。C/C++会把常量字符串存储到单独的一个内存区域,当几个指针。指向同一个字符串的时候,他们实际会指向同一块内存
  • 用相同的常量字符串去初始化不同的数组的时候就会开辟出不同的内存块。所以str1和str2不同,str3和str4不同

二.指针数组
 

1.讲解 

  • 指针数组是一个数组,其中的每个元素都是指针。
  • 它可以存储多个指针,每个指针可以指向不同类型的数据。
  • 声明指针数组的语法为:type *ptr[size],其中type是指针指向的数据类型,size是数组的大小

示例:int num1 = 10, num2 = 20, num3 = 30;

           int *ptr[3] = {&num1, &num2, &num3};

           // 声明一个包含3个整型指针的数组 

2.练习

用指针数组来模拟二维数组

int main()
{
	int arr1[4] = { 1,2,4,5 };
	int arr2[4] = { 2,2,5,5 };
	int arr3[4] = { 1,1,4,4 };

	int* pa[3] = { &arr1,&arr2,&arr3 };

	for (int i = 0; i < 3; i++)
	{
		for (int j = 0; j < 4; j++)
		{
			printf("%d ", pa[i][j]);
		}
		printf("\n");
	}
	return 0;
}

 


三.数组指针


1.数组指针的定义
 

  • 数组指针是指向数组的指针变量。
  • 它可以指向一个数组的首元素,也可以指向整个数组。
  • 声明数组指针的语法为:type (*ptr)[size],其中type是数组元素的类型,size是数组的大小

示例:int arr[5] = {1, 2, 3, 4, 5};

           int (*ptr)[5] = &arr; // 声明一个指向包含5个整数的数组的指针

2.数组指针与指针数组在语法上的对比 

int *p1[10];
int (*p2)[10];

int (*p)[10];为数组指针
//解释:p先和*结合,说明p是一个指针变量,然后指着指向的是一个大小为10个整型的数组。所以p是一个指针,指向一个数组,叫数组指针。
//这里要注意:[]的优先级要高于*号的,所以必须加上()来保证p先和*结合

int *p1[10];为指针数组

//解释:p先和[]结合,说明p是一个数组,然后数组的类型为int*

3.&数组名VS数组名
 

  •  &arr和arr,虽然值是一样的,但是意义应该不一样的
  •  &arr 表示的是数组的地址,而不是数组首元素的地址,数组的地址+1,跳过整个数组的大小
  • 数组名是数组首元素的地址,但有两个例外:

1.sizeof(数组名),这里的数组名表示整个数组,sizeof(数组名)计算的是整个数组的大小,单位是字节。

2.&数组名,这里的数组名表示整个数组,取出的是数组的地址

 

4.数组指针的使用 

void print_arr(int(*arr)[5], int row, int col)
{
	for (int i = 0; i < row; i++)
	{
		for (int 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 };
	//数组名arr,表示首元素的地址
	//但是二维数组的首元素是二维数组的第一行
	//所以这里传递的arr,其实相当于第一行的地址,是一维数组(有五个元素)的地址
	//可以数组指针来接收
	print_arr(arr, 3, 5);
	return 0;
}
  •  int arr[5];   arr是一个能够存放5个整型数据的数组
  • int *parr1[10];  parr1是一个数组,数组有10个元素,每个元素的类型是int*
  • int (*parr2)[10];   parr2是一个指针,该指针是指向数值的,指向的数组有10个元素,每个元素的类型是int
  • int (*parr3[10])[5];  parr3是一个数组,是存放数组指针的数组,这个数组有10个元素,存放的这个数组指针指向的数组有5个元素,每个元素是int类型。

理解:parr3[10]可知是一个数组,int (*     )[5]是一个数组指针类型,所以总的看是一个存放数组指针类型的数组。


 四.数组参数、指针参数

1.一维数组传参
 

  •  数组传参,形参是可以写成数组形式
  •  数组传参的本质是传递了数组首元素的地址,形参也可以是指针
void test(int arr[])//可以    数组传参,形参是可以写成数组形式的
{}
void test(int arr[10])//可以
{}
void test(int* arr)//可以     数组传参的本质是传递了数组首元素的地址,形参也可以是指针
{}
void test2(int* arr[20])//可以 
{}
void test2(int** arr)//可以  传过来的是int* 的地址,就用int**来接收
{}
int main()
{
	int arr[10] = { 0 };

	int* arr2[20] = { 0 };
	test(arr);
	test2(arr2);
}

 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);
}

 3.一级指针传参

 形参的部分写成一级指针就行了

void print(int* p, int sz)  //形参的部分写成一级指针就行了
{
	int i = 0;
	for (i = 0; i < sz; i++)
	{
		printf("%d\n", *(p + i));
	}
}
int main()
{
	int arr[10] = { 1,2,3,4,5,6,7,8,9 };
	int* pa = arr;
	int sz = sizeof(arr) / sizeof(arr[0]);
	//一级指针p,传给函数
	print(pa, sz);
	return 0;
}

4.二级指针传参
 

就用二级指针来接收 

 

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;
}

思考:当函数的参数为二级指针的时候,可以接收什么参数

只要是一级指针的地址就行:

int a=10;

int* p=&a;

int** pp=&p;

test(&p);     test(pp);

int* arr[10];  指针数组,首元素为一级指针,传过来首元素的地址

test(arr); 


这次的内容梳理就先到这里了,我会加快更新后续内容的,感谢大家的支持!!! 

 

 

 

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

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

相关文章

Python py文件打包成 exe文件

文章目录 安装 pyinstaller 模块pyinstaller 的使用pyinstaller 常用参数多文件打包 安装 pyinstaller 模块 pip install pyinstaller -i https://pypi.tuna.tsinghua.edu.cn/simple在 pyinstaller 模块安装成功之后&#xff0c;在 Python 的安装目录下的 Scripts 目录下会增加…

华为云云耀云服务器L实例评测|用PHP从数据库到后端到前端完整实现一个中秋节祝福语项目

&#x1f3c6;作者简介&#xff0c;黑夜开发者&#xff0c;CSDN领军人物&#xff0c;全栈领域优质创作者✌&#xff0c;CSDN博客专家&#xff0c;阿里云社区专家博主&#xff0c;2023年6月CSDN上海赛道top4。 &#x1f3c6;数年电商行业从业经验&#xff0c;历任核心研发工程师…

小程序隐私弹窗的实现

小程序的开发者对于微信官方来说是有爱有恨&#xff0c;三天二头整事是鹅厂的一贯风格。 隐私弹窗的几个要点 回归正题&#xff0c;小程序隐私弹窗的几个要点&#xff1a; 1、何时弹出用户隐私协议的弹窗&#xff1f; 2、是每次进小程序都弹出来吗&#xff1f; 这两个想明…

info文档与man手册

man 手册 man --version# 查看版本 man 2 socket# 查看section2中的socket yum install man-pages# 更新man手册man -f socket# 列出所有章节的socket # man -f刚开始使用的时候不显示 # centos7执行mandb命令,7以下的版本执行makewhatis命令 # 之后执行man -f就生效了 [rootk…

scrapyd-完整细节

安装scrapyd服务 pip install scrapyd 安装scrapyd客户端 pip install scrapyd-client 安装好以后重新开启cmd输入命令 scrapyd 出现以下结果代表安装成功 打开浏览器输入网址&#xff0c;即可打开界面客户端 http://127.0.0.1:6800/ 回车后显示一下ok内容代表部署成功 回到服…

系统性能调优:提升服务器响应速度

&#x1f337;&#x1f341; 博主猫头虎&#xff08;&#x1f405;&#x1f43e;&#xff09;带您 Go to New World✨&#x1f341; &#x1f984; 博客首页——&#x1f405;&#x1f43e;猫头虎的博客&#x1f390; &#x1f433; 《面试题大全专栏》 &#x1f995; 文章图文…

servlet 引用src目录下子目录的class文件方法

1、MyServlet class文件所处的目录结构如下&#xff1a; 2、如果在url里直接引用是不行的&#xff0c;http://localhost:9092/GetRequest_Web_exploded/MyServlet 3、需要在web.xml映射后才行&#xff1a; MyServlet com.example.MyServlet <servlet-mapping><ser…

【少儿编程的网站应该怎么选择】

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;元宇宙-秩沅 &#x1f468;‍&#x1f4bb; hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍&#x1f4bb; 本文由 秩沅 原创 &#x1f468;‍&#x1f4bb; 收录于专栏&#xff1a;效率…

Ubuntu安装中文拼音输入法

ubuntu安装中文拼音输入法 ubuntu版本为23.04 1、安装中文语言包 首先安装中文输入法必须要让系统支持中文语言&#xff0c;可以在 Language Support 中安装中文语言包。 添加或删除语音选项&#xff0c;添加中文简体&#xff0c;然后会有Applying changes的对话框&#x…

vue项目使用vue-video-player实现视频直播功能

文章目录 引言一、基本使用1. 播放mp42. options常用属性3. 常用事件 二、使用videojs-contrib-hls播放m3u8三、视频链接测试工具potplayer 引言 随着互联网的快速发展&#xff0c;视频直播已经成为了越来越受欢迎的一种媒体形式。而在开发一个拥有视频直播功能的网站或应用时…

Java中StringBuilder常见的操作方法

文章目录 1.创建字符串2.追加字符串3.替换字符串4.删除字符串5.插入字符串6.字符串反转7.其他操作 在 Java 中字符串不属于基本数据类型&#xff0c;而是对象。Java 提供了 String 类来创建和操作字符串&#xff0c;但String 类是不可变类&#xff0c;一旦一个 String 对象被创…

Win2016安装安全狗和DVWA

搭建安全狗之前需要先安装XAMPP&#xff0c;XAMPP&#xff08;ApacheMySQLPHPPERL&#xff09;是一个功能强大的建站集成软件包&#xff0c;这个软件包原来的名字是 LAMPP&#xff0c;这个软件类似于phpstudy&#xff0c;功能比phpstudy强大 Download XAMPP (apachefriends.or…

人脸图像数据增强

为什么要做数据增强 在计算机视觉相关任务中&#xff0c;数据增强&#xff08;Data Augmentation&#xff09;是一种常用的技术&#xff0c;用于扩展训练数据集的多样性。它包括对原始图像进行一系列随机或有规律的变换&#xff0c;以生成新的训练样本。数据增强的主要目的是增…

华为杯数学建模比赛经验分享

再过一周左右,第二十届华为杯数学建模比赛就要开赛了&#xff0c;所以今天分享一下个人数学建模比赛的经验。 今天给大家分享一期关于华为杯数学建模比赛的经验分享&#xff0c;我将从以下三个方面展开说明&#xff1a; &#xff08;1&#xff09;如何准备数学建模比赛&#x…

ELK日志分析系统+ELFK(Filebeat)

本章结构&#xff1a; 1、ELK日志分析系统简介 2、Elasticsearch介绍&#xff08;简称ES&#xff09; 3、Logstash介绍 4、Kibana介绍 5、实验&#xff0c;ELK部署 一、ELK日志分析系统简介 ELK平台是一套完整的日志集中处理解决方案&#xff0c;将 ElasticSearch、Logst…

Ubuntu修改静态IP、网关和DNS的方法总结

Ubuntu修改静态IP、网关和DNS的方法总结 ubuntu系统&#xff08;其他debian的衍生版本好像也可以&#xff09;修改静态IP有以下几种方法。&#xff08;搜索总结&#xff0c;可能也不太对&#xff09; /etc/netplan (use) Ubuntu 18.04开始可以使用netplan配置网络&#xff0…

2.4GHz、DA14530-00000FX2射频收发器/LSM6DSOTR 6 轴运动传感器/SKY66423-11射频前端 860MHz 至 930MHz

一、2.4GHz、DA14530-00000FX2射频收发器 IC DA14530是一款超低功耗蓝牙5.1 SoC。它集成了2.4 GHz CMOS收发器和ARMCortex-M0微控制器&#xff0c;具有48 kB RAM和32 kB一次性可编程&#xff08;OTP&#xff09;存储器。无线电收发器、基带处理器和合格的Bluetooth低功耗堆栈完…

Android13适配-Google官方照片视频选择器

官方照片选择器 图 1. 照片选择器提供了一个直观的界面&#xff0c;便于与您的应用分享照片。 照片选择器的界面可供浏览和搜索&#xff0c;并按日期降序向用户显示其媒体库中的文件。如隐私保护最佳实践 Codelab 中所示&#xff0c;照片选择器为用户提供了一种安全的内置授权…

代码随想录算法训练营day56|583. 两个字符串的删除操作|72. 编辑距离

583. 两个字符串的删除操作 力扣题目链接 给定两个单词 word1 和 word2&#xff0c;找到使得 word1 和 word2 相同所需的最小步数&#xff0c;每步可以删除任意一个字符串中的一个字符。 示例&#xff1a; 输入: “sea”, “eat” 输出: 2 解释: 第一步将"sea"变…

Android StateFlow初探

Android StateFlow初探 前言&#xff1a; 最近在学习StateFlow&#xff0c;感觉很好用&#xff0c;也很神奇&#xff0c;于是记录了一下. 1.简介&#xff1a; StateFlow 是一个状态容器式可观察数据流&#xff0c;可以向其收集器发出当前状态更新和新状态更新。还可通过其 …