指针(二)------字符指针+数组指针+指针与数组(传参)

news2024/11/20 1:48:56

💓博主csdn个人主页:小小unicorn
⏩专栏分类:C语言
🚚代码仓库:小小unicorn的代码仓库🚚
🌹🌹🌹关注我带你学习编程知识

前言
在指针(一)中,我们已经知道了指针的基本用法:

1.指针就是一个用于存放地址的变量,地址唯一标识一块内存空间。

2.指针的大小是固定的4/8个字节(32位平台/64位平台)。
3.指针是有类型的,指针的类型决定了指针±整数的步长和指针解引用操作时的权限大小。
4.指针的相关运算。

今天,我们继续来学习指针更深层次的内容。

指针(二)

  • 字符指针
  • 指针数组
  • 数组指针
    • 定义
    • 数组名与&
    • 数组指针的应用
  • 数组参数与指针参数(传参)
    • 一维数组
    • 二维数组
    • 一级指针
    • 二级指针

字符指针

在指针的类型中有一种指针类型叫字符指针char * 。
使用方法为:

#include<stdio.h>
int main()
{
	char ch = 'w';
	char* p = &ch;
	return 0;
}

代码中,将字符变量ch的地址存放在了字符指针p中。

字符指针还有另一种使用方式:

#include<stdio.h>
int main()
{
	char* p = "hello csdn.";
	printf("%c\n", *p);//打印字符'h'
	printf("%s\n", p);//打印字符串"hello csdn."
	return 0;
}

字符指针p中存放的并非字符串"hello csdn.",字符指针p中存放的是字符串"hello csdn.“的首元素地址,即字符’h’的地址。

所以,当对字符指针p进行解引用操作并以字符的形式打印时只能打印字符’h’。我们知道,打印一个字符串只需要提供字符串的首元素地址即可,既然字符指针p中存放的是字符串的首元素地址,那么我们只要提供p(字符串首地址)并以字符串的形式打印,便可以打印字符串"hello csdn.”。

注意:代码中的字符串"hello csdn."是一个常量字符串。

指针数组

指针数组也是数组,是用于存放指针的数组。

int* arr3[5];

在这里插入图片描述
以此内推:

char* arr4[10];//数组arr4包含10个元素,每个元素是一个一级字符型指针。
char** arr5[5];//数组arr5包含5个元素,每个元素是一个二级字符型指针。

数组arr4包含10个元素,每个元素是一个一级字符型指针;数组arr5包含5个元素,每个元素是一个二级字符型指针

数组指针

定义

整型指针是指向整型的指针,字符指针是指向字符的指针,那么依次内推:数组指针应该就是指向数组的指针了。

整型指针和字符指针,在使用时只需取出某整型/字符型的数据的地址,并将地址存入整型/字符型指针即可。

#include<stdio.h>
int main()
{
	int a = 10;
	int* pa = &a;//取出a的地址存入整型指针中
	char ch = 'w';
	char* pc = &ch;//取出ch的地址存入字符型指针中
	return 0;
}

数组指针也是一样,我们只需取出数组的地址,并将其存入数组指针即可。

#include<stdio.h>
int main()
{
	int arr[10] = { 0 };
	int(*p)[10] = &arr;
	//&arr - 数组的地址
	return 0;
}

那么数组指针的指针类型是如何写出来的呢?
我们应该知道的是:
1. [ ]的优先级要高于 * 。
2. 一个变量除去了变量名,便是它的变量类型。比如:

int a = 10;//除去变量名a,变量类型为int
char ch = 'w';//除去变量名ch,变量类型为char
int* p = NULL;//除去变量名p,变量类型为int*


数组其实还可以这样理解:

int arr[10] = { 0 };//除去变量名arr,变量类型为int [10]
int arr[3][4] = { 0 };//除去变量名arr,变量类型为int [3][4]
int* arr[10] = { 0 };//除去变量名arr,变量类型为int* [10]

在这里插入图片描述

3. 一个指针变量除去了变量名和 * ,便是指针指向的内容的类型。比如:

int a = 10;
int* p = &a;//除去变量名(p)和*,便是P指向的内容(a)的类型->int
char ch = 'w';
char* pc = &ch;//除去变量名(pc)和*,便是pc指向的内容(ch)的类型->char

知道这些,我们可以来写一个数组指针的指针类型:

#include<stdio.h>
int main()
{
	int arr[10] = { 0 };
	int(*p)[10] = &arr;
	//&arr - 数组的地址
	return 0;
}

在这里插入图片描述

数组名与&

数组名代表整个数组的地址的情况其实只有两种

1.&数组名。
2.数组名单独放在sizeof内部,即sizeof(数组名)。
除此之外,所有的数组名都是数组首元素地址。

例如:

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

对于该数组arr,只有以下两种情况数组名代表整个数组的地址:

	&arr;
	sizeof(arr);//arr单独放在sizeof内部

除此之外,所以的arr都代表数组首元素地址,即1的地址
我们指针联系起来就是:

#include<stdio.h>
int main()
{
	int arr[5] = { 1, 2, 3, 4, 5 };
	int* p1 = arr;//数组首元素的地址
	int(*p2)[5] = &arr;//数组的地址
	printf("%p\n", p1);
	printf("%p\n", p2);

	printf("%p\n", p1+1);
	printf("%p\n", p2+1);
	return 0;
}

因为代码中的arr是数组首元素地址,所以要用int * 的指针接收。而&arr是整个数组的地址,所以要用数组指针进行接收。

虽然一个是数组首元素地址,一个是数组的地址,但是它们存放的都是数组的起始位置的地址,所以将p1和p2以地址的形式打印出来发现它们的值一样。

数组首元素地址和数组的地址的区别在于,数组首元素地址+1只能跳过一个元素指向下一个元素,而数组的地址+1能跳过整个数组指向数组后面的内存空间。
在这里插入图片描述

数组指针的应用

最简单的应用就是打印二维数组

#include<stdio.h>
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));
		}
		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;
}

在这里我们打印一个三行五列的二维数组。传参时我们传入二维数组的数组名,明确打印的起始位置;传入行数和列数,明确打印的数据范围。

通过上面对&数组名和数组名的认识,我们知道了这里传入的数组名代表的是二维数组的首元素地址,而二维数组的首元素第一行的元素,即传入的是一维数组的地址,所以我们必须用数组指针进行接收。
打印时,通过表达式 * (*(p+i)+j ) 锁定打印目标。

数组参数与指针参数(传参)

一维数组

#include<stdio.h>
void test1(int arr[10])//数组接收
{}
void test1(int *arr)//指针接收
{}
void test2(int *arr[20])//数组接收
{}
void test2(int **arr)//指针接收
{}
int main()
{
	int arr1[10] = { 0 };//整型数组
	int *arr2[20] = { 0 };//整型指针数组
	test1(arr1);
	test2(arr2);
}

整型数组
当向函数传入整型数组的数组名时,我们有以下几种参数可供接收:

1.数组传参数组接收,我们传入的是整型数组,那我们就用整型数组接收。
2.传入的数组名本质上是数组首元素地址,所以我们可以用指针接收。
3.数组的元素类型是整型,我们接收整型元素的地址用int * 的指针即可。

整型指针数组
当向函数传入整型指针数组的数组名时,我们有以下几种参数可供接收:

1.数组传参数组接收,我们传入的是整型指针数组,那我们就用整型指针数组接收。
2.指针接收,数组的元素是int * 类型的,我们接收int * 类型元素的地址用二级指针int ** 即可。

注意:一维数组传参,函数形参设计时[ ]内的数字可省略

二维数组

#include<stdio.h>
void test(int arr[][5])//数组接收
{}
void test(int(*arr)[5])//指针接收
{}
int main()
{
	int arr[3][5] = { 0 };//二维数组
	test(arr);
}

当向函数传入二维数组的数组名时,我们有以下几种参数可供接收:

1.二维数组传参二维数组接收。
2.指针接收,二维数组的首元素是二维数组第一行的地址,即一维数组的地址,我们用数组指针接收即可。

注意:二维数组传参,函数形参的设计只能省略第一个[ ]内的数字。

一级指针

#include<stdio.h>
void print(int* p, int sz)//一级指针接收
{
	int i = 0;
	for (i = 0; i < sz; i++)
	{
		printf("%d ", *(p + i));
	}
}
int main()
{
	int arr[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
	int sz = sizeof(arr) / sizeof(arr[0]);
	int* p = arr;//一级指针
	print(p, sz);
	return 0;
}

当我们传入的参数为一级指针时,我们可以用一级指针的形参对其进行接收,那么当函数形参为一级指针的时候,传入什么样的参数,具体看下面代码:

#include<stdio.h>
void test(int* p)
{}
int main()
{
	int a = 10;
	test(&a);//可以传入变量的地址
	int* p = &a;
	test(p);//可以传入一级指针
	int arr[10] = { 0 };
	test(arr);//可以传入一维数组名
	//...
	return 0;
}

总结:只要传入的表达式最终的类型是一级指针类型即可传入。

二级指针

#include<stdio.h>
void test(int** p)//二级指针接收
{}
int main()
{
	int a = 10;
	int* pa = &a;
	int** paa = &pa;
	test(paa);//二级指针
	return 0;
}

当我们传入的参数为二级指针时,我们可以用二级指针的形参对其进行接收,那么当函数形参为二级指针的时候,可以传入什么样的参数具体看下面代码:

#include<stdio.h>
void test(int** p)
{}
int main()
{
	int a = 10;
	int* pa = &a;
	test(&pa);//可以传入一级指针的地址
	int** paa = &pa;
	test(paa);//可以传入二级指针
	int* arr[10];
	test(arr);//可以传入一级指针数组的数组名
	//...
	return 0;
}

总结:只要传入的表达式最终的类型是二级指针类型即可传入。

总结:

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

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

相关文章

[医学图像知识]CT图和PET图的成像表现形式

1.CT图通常来说是单通道灰色图&#xff0c;用灰度值表示了结构对于x射线的吸收程度。 2.PET/SPECT图最初也是灰度图&#xff0c;用灰度值表示细胞的反射gama射线的程度&#xff0c;但是为了更好的观测不同细胞等的区别&#xff0c;通常将灰度图转化为了 伪彩色图像。 找个例子…

原生js值之数据类型详解

js的数据类型 数据类型分类基本数据类型boolean:布尔类undefined:未定义的值null类型数值转换 NumberparseInt 转换整数 parseFloat转换浮点数 String类型特点如何转换成字符串模板字面量字符串插值模板字面量标签函数 symbol类型特性使用 BigInt类型复杂数据类型Object类属性与…

卡奥斯第二届1024程序员节正式启动!

代码改变世界&#xff0c;开源创造未来&#xff0c;卡奥斯第二届1024程序员节开始啦&#xff01; 本次活动设置4个线上活动分会场: 低代码分会场、开源分会场、知识分会场和产品分会场&#xff0c;共12个奖项&#xff0c;1100多个奖品&#xff0c;雷神911X猎荒者游戏本&#x…

一文搞定Postman(菜鸟必看)

什么是Postman&#xff1f; Postman是一个可扩展的 API 测试工具&#xff0c;可以快速集成到 CI/CD 管道中。它于 2012 年作为 Abhinav Asthana 的一个副项目启动&#xff0c;旨在简化测试和开发中的 API 工作流程。API 代表应用程序编程接口&#xff0c;它允许软件应用程序通…

【JVM】类加载器

类与类加载器 类加载器虽然只用于实现类的加载动作&#xff0c;但它在Java程序中起到的作用却远超类加载阶段。对于任意一个类&#xff0c;都必须由加载它的类加载器和这个类本身一起共同确立其在Java虚拟机中的唯一性&#xff0c;每 一个类加载器&#xff0c;都拥有一个独立的…

k8s 中master 与node的通信

一、Master 节点与 Node 节点通讯原理 Master 节点启动时&#xff0c;会运行一个 kube-apiserver 进程&#xff0c;它提供了集群管理的 API 接口&#xff0c;是集群内各个功能模块之间数据交互和通信的中心枢纽&#xff0c;并且它页提供了完备的集群安全机制。在 Node 节点上&a…

【新品发布】洛微科技全新工业级高性能 D系列 TOF相机D3重磅上线!

近日&#xff0c;洛微科技对外发布新款高性能D系列 TOF相机D3&#xff0c;这是一款专为工业环境中高性能操作设计的3D TOF智能相机。 D3基于行业领先的Sony DepthSense像素技术开发&#xff0c;具有毫米级测量精度、VGA深度分辨率、抗环境光能力强、软/硬件多触发方式、HDR适配…

夸克扫描王识别精度领跑行业 愿携手各方伙伴探索AIGC应用新范式

日前&#xff0c;在“AIGC与场景化应用创新”主题研讨会上&#xff0c;阿里智能信息事业群夸克视觉技术负责人黄锐华分享了AI技术应用于扫描场景的最新成果。他表示&#xff0c;AIGC给手机扫描产品打开了创新空间&#xff0c;搭载大模型技术的夸克扫描王对识别手写字体、复杂公…

【验证码逆向专栏】螺丝帽人机验证逆向分析

声明 本文章中所有内容仅供学习交流使用&#xff0c;不用于其他任何目的&#xff0c;不提供完整代码&#xff0c;抓包内容、敏感网址、数据接口等均已做脱敏处理&#xff0c;严禁用于商业用途和非法用途&#xff0c;否则由此产生的一切后果均与作者无关&#xff01; 本文章未…

Maven 查看项目中的依赖

文章目录 通过 Maven 命令查看依赖dependency:listdependency:tree将命令结果输出到文档 视图化查看依赖Maven HelperIDEA 自带工具 想查看项目中使用的依赖列表时&#xff0c;可以参考下面几种方式 通过 Maven 命令查看依赖 在有 pom.xml 的路径下&#xff0c;通过命令行工…

人工智能(pytorch)搭建模型19-手把手利用pytorch框架搭建目标检测DarkNet模型,并展现网络结构

大家好&#xff0c;我是微学AI&#xff0c;今天给大家介绍一下人工智能(pytorch)搭建模型19-手把手利用pytorch框架搭建目标检测DarkNet模型&#xff0c;并展现网络结构。随着深度学习技术的不断发展&#xff0c;各种卷积神经网络模型层出不穷&#xff0c;其中DarkNet作为一种快…

CMD脚本实战教程

要在 Windows 11 上编写一个自定义关机的 CMD 脚本文件&#xff0c;你可以创建一个扩展名为 .bat 或 .cmd 的文本文件&#xff0c;并在其中编写脚本。 一、常用语法 rem&#xff1a;注释 pause&#xff1a;暂停正在执行的批处理文件&#xff0c;并提示用户按键之后继续执行 r…

VisualStudio2017社区版安装完毕后,找不到stdio.h等头文件的解决方案

安装完VisualStudio2017社区版后&#xff0c;创建一个C的测试项目&#xff0c;好使&#xff0c;一时心血来潮创建了纯C的项目&#xff0c;结果死活提示找不到头文件“stdio.h”&#xff0c;测试代码如下&#xff1a; #include<stdio.h>int main() {printf("Hello w…

超详细 | CISP-信息安全专业认证考前攻略

近年来&#xff0c;中央关于信息安全的政策不断加码&#xff0c;网络安全已上升到国家战略&#xff0c;安全专业人才缺口以每年1.5万人的速度递增。作为信息安全从业人员&#xff0c;持证上岗已是大势所趋。今天&#xff0c;重点聊一下信息安全国内第一认证CISP&#xff01; 注…

关于表单快速开发低代码技术平台的内容介绍

运用什么样的表单快速开发软件平台可以实现高效率创收&#xff1f;随着科技的进步和飞速发展&#xff0c;专业的低代码技术平台已经走入了很多企业的办公职场中&#xff0c;它们灵活、轻量级、优质、高效、易维护等优势特点&#xff0c;可以高效助力广大企业提质增效&#xff0…

php代码审计篇bluecms代码审计

文章目录 Seay自动审计源码分析/ad_js.php文件sql注入分析/include/common.fun.php注入分析/admin/login.php存在宽字节注入分析/admin/nav.php SQL注入分析前台注册界面存在存储型xss Seay自动审计 使用seay进行自动代码审计 源码分析 /ad_js.php文件sql注入分析 查看执行…

k8s-部署

1.k8s 集群与部署 更改所有主机名字和解析 k8s1 192.168.25.11 reg.westos.org,habbor 仓库 k8s2 192.168.25.12 master&#xff0c;k8s 集群控制节点 k8s3 192.168.25.13 node&#xff0c;k8s 集群工作节点 k8s4 192.168.25.14 node&#xff0c;k8s 集群工作节点 所有节…

不再跳票Fedora 26 正式发布!

经过延期和跳票&#xff0c;Fedora 26终于和大家见面了&#xff0c;下面是Fedora 项目负责人Matthew Miller感谢信 大家好&#xff0c;我很高兴地宣布&#xff0c;从即刻起 Fedora 26 正式可用了。你可以从下面了解到具体信息&#xff0c;也可以马上开始下载&#xff1a; •下载…

漫画工厂ai-comic-factory 文字2漫画

demo入口https://huggingface.co/spaces/jbilcke-hf/ai-comic-factory 最终展示 大概流程&#xff1a; 选漫画分格输入需要将啥故事X X 通过Llama2 70B 生成具体的每个分割图的描述YY 通过SDXL 生成图 LLM: llama-2 is used to generate the captions of 4 comic panels (pro…

【从0学习Solidity】 6. 引用类型, array, struct

【从0学习Solidity】 6. 引用类型, array, struct 博主简介&#xff1a;不写代码没饭吃&#xff0c;一名全栈领域的创作者&#xff0c;专注于研究互联网产品的解决方案和技术。熟悉云原生、微服务架构&#xff0c;分享一些项目实战经验以及前沿技术的见解。关注我们的主页&…