C 练习实例77-指向指针的指针-二维数组

news2024/11/16 20:28:11

关于数组的一些操作

#include<stdio.h>
#include<stdio.h>
void fun(int b[],int length)
{
	for(int i=0;i<length;i++){
		printf("%d ",b[i]);
	}
	printf("\n");
	for(int i=0;i<length;i++){	//数组作为形参传递,传递的是指针,所以能够改变值
		b[i]++;
	}
}
int main()
{
	int a[5]={1,2,3,4,5};
//	int b[5]=a;  不合法,数组的本质是常量指针,不允许被修改
//	也就是说b指向了一片空间,这片空间是随机分配的,它一辈子只能指向那片空间
	fun(a,sizeof(a)/sizeof(int));
	for(int i=0;i<sizeof(a)/sizeof(int);i++){
		printf("%d ",a[i]);
	}
	printf("\n");
	return 0;
}

运行结果

1 2 3 4 5
2 3 4 5 6

指向指针的指针

代码 

#include<stdio.h>
int main()
{
	int a=100;
	int *p1=&a;
	int **p2=&p1;
	
	printf("&a=%p\n",&a);
	printf("p1=%p\n",p1);
	printf("*p2=%p\n",*p2);
	
	printf("a=%d\n",a);
	printf("*p1=%d\n",*p1);
	printf("**p2=%d\n",**p2);
	
	return 0;
}

 结果

&a=000000000065FE14
p1=000000000065FE14
*p2=000000000065FE14
a=100
*p1=100
**p2=100

二维数组

代码

#include<stdio.h>
int main()
{
//	要点:数组名可以当指针用,它的值就是首地址,它指向的就是数组首元素
	int b[3]={1,2,3};//一维数组
	printf("b=%p\n",b);//首地址
	printf("&b=%p\n",&b);//首地址
	printf("&b[0]=%p\n",&b[0]);//首地址
	printf("*b=%d\n",*b);//首地址可以取出首元素
	printf("b[0]=%d\n",b[0]);
	
	printf("\n");
	/*
	二维数组的每一行其实就是一个一维数组
	a[0]可以认为是第一行数组的数组名,也可以认为是指向第一行数组的指针
	a[0]的值实际上就是第一行数组的首地址
	以此类推,a[1]是第二行,a[2]是第三行......
	*/
	
//	{a[0],a[1],a[2]}也可以看作是一个一维数组,a是它的名,也可以看作是指针
//	a的值就是就是一维数组a[0]的首地址
	int a[3][4]={{0,1,2,3},{4,5,6,7},{8,9,10,11}};//二维数组
	printf("a[0]=%p\n",a[0]);//第一行数组的首地址,也就是首地址
	printf("&a[0]=%p\n",&a[0]);//第一行数组的首地址,也就是首地址
	printf("*a=%p\n",*a);//第一行数组的首地址,也就是首地址
	printf("a=%p\n",a);//第一行数组的首地址,也就是首地址
	printf("&a=%p\n",&a);//第一行数组的首地址,也就是首地址
	printf("&a[0][0]=%p\n",&a[0][0]);//第一行数组的首地址
	printf("a[0][0]=%d\n",a[0][0]);//首元素
	printf("*a[0]=%d\n",*a[0]);//首地址可以取出首元素
	printf("**a=%d\n",**a);//首地址的首地址可以取出首元素-指针的指针
		
	return 0;
}

运行结果

b=000000000065FE14
&b=000000000065FE14
&b[0]=000000000065FE14
*b=1
b[0]=1

a[0]=000000000065FDE0
&a[0]=000000000065FDE0
*a=000000000065FDE0
a=000000000065FDE0
&a=000000000065FDE0
&a[0][0]=000000000065FDE0
a[0][0]=0
*a[0]=0
**a=0

在一维数组中,a的值=&a的值=&a[0]的值,*a=a[0]

在二维数组中,&a=a=*a=a[0]=&a[0]=&a[0][0],a[0][0]=*a[0]=**a[0],有点绕哈,是不是和指向指针的指针有点像。

数组指针(指向数组的指针)

它的定义如下:

#include <stdio.h>
int main()
{
	int a[3]={1,2,3};
	int *p=a;
	printf("*p+0=%d\n",*p+0);
	printf("*p+1=%d\n",*p+1);
	printf("*p+2=%d\n",*p+2);
}

输出结果

*p+0=1
*p+1=2
*p+2=3

数组指针,就是指向数组的指针,它存放的是数组的首地址,每加1其实是加了一个int类型的字节长度。

指针数组

指针数组,就是数组的每个元素是指针类型的,存放的是地址值。

#include <stdio.h>
int main()
{
	int a=1;
	int b=2;
	int c=3;
	printf("%d,%d,%d\n",&a,&b,&c);
	int *array[3]={&a,&b,&c};
//int *->int型指针,array[3]->数组有3个元素,每个元素是int *型,即指向整形变量的指针类型
	printf("%d,%d,%d\n",array[0],array[1],array[2]);
	printf("%d,%d,%d\n",*array[0],*array[1],*array[2]);//*为取值运算符
	
	printf("%d\n",&array[0]);//(数组也有它自己的地址)
	printf("%d\n",array);//&array[0]=array=&array
	printf("%d\n",&array);//&array[0]=array=&array
	
//	int *p=array;××因为array是int *型的,所以我们要定义int *型的指针,才能指向这个数组
	int **p=array;//拆成3部分看容易理解,int *看作类型,*表示是int *类型的指针,p代表变量名
	//即指向指针的指针
	printf("%d,%d,%d\n",&array[0],&array[1],&array[2]);//(数组也有它自己的地址)
	printf("%d,%d,%d\n",p,p+1,p+2);//(通过指针拿到数组单元的地址)
	printf("%d,%d,%d\n",*(p+0),*(p+1),*(p+2));//(通过取值运算符*拿到数组单元的值)
	printf("%d,%d,%d\n",**(p+0),**(p+1),**(p+2));//(通过取值运算符*拿到数组单元的地址所指向的值)
	
//在自己动手实验的过程中,我发现变量的内存分配好像是自顶向下,是递减规律
//而数组单元间的地址值是递增规律
	
}

运行结果 

6684180,6684176,6684172
6684180,6684176,6684172
1,2,3
6684144
6684144
6684144
6684144,6684152,6684160
6684144,6684152,6684160
6684180,6684176,6684172
1,2,3

二维数组续

 

#include <stdio.h>
int main()
{
	int a[3][4]={{0,1,2,3},{4,5,6,7},{8,9,10,11}};
	int *p0=a[0];//第一层首元地址
	int *p1=a[1];//第二层首元地址
	int *p2=a[2];//第三层首元地址
	printf("*p0=%d\n",*p0);
	printf("*p1=%d\n",*p1);
	printf("*p2=%d\n",*p2);
	printf("*a[0]=%d\n",*a[0]);
	printf("*a[1]=%d\n",*a[1]);
	printf("*a[2]=%d\n",*a[2]);
	int (*p)[4]=a;//p指向int[4],即指向4个int类型的连续空间,4*4=16Byte
	printf("a[0]=%d\n",a[0]);
	printf("a[1]=%d\n",a[1]);
	printf("a[2]=%d\n",a[2]);
	printf("\n");
	printf("p0=%d\n",p0);
	printf("p1=%d\n",p1);
	printf("p2=%d\n",p2);
	printf("\n");
	printf("p+0=%d\n",p+0);//二维数组第一层
	printf("p+1=%d\n",p+1);//+1不是简单的加1,而是加到下一个16Byte的空间  第二层
	printf("p+2=%d\n",p+2);//二维数组第三层
	printf("\n");
	
	printf("*(*(p+0)+0)=%d\n",*(*(p+0)+0));
	printf("*(*(p+0)+0)=%d\n",*(*(p+1)+0));
	printf("*(*(p+0)+0)=%d\n",*(*(p+2)+0));
	printf("\n");
	
//	因此遍历二维数组就有了两种方式
//	方式一
	for(int i=0;i<3;i++){	//最外层控制行
		for(int j=0;j<4;j++){	//内层控制列
			printf("%d ",a[i][j]);
		}
		printf("\n");
	}
	printf("\n");
//	方式二
	for(int i=0;i<3;i++){	//最外层控制行
		for(int j=0;j<4;j++){	//内层控制列
			printf("%d ",*(*(p+i)+j));
		}
		printf("\n");
	}
//	总结:c语言里的二维数组是连续空间,所以可以进行上述操作
	return 0;
}

运行 

*a[0]=0
*a[1]=4
*a[2]=8
a[0]=6684096
a[1]=6684112
a[2]=6684128

p0=6684096
p1=6684112
p2=6684128

p+0=6684096
p+1=6684112
p+2=6684128

*(*(p+0)+0)=0
*(*(p+0)+0)=4
*(*(p+0)+0)=8

0 1 2 3
4 5 6 7
8 9 10 11

0 1 2 3
4 5 6 7
8 9 10 11

指针+字符串

#include <stdio.h>
int main()
{	
	//好好学习,天天向上。
	char *str1="好好学";
	char *str2="习,天";
	char *str3="天向上";
	char *str[3]={str1,str2,str3};
	printf("%s%s%s",str[0],str[1],str[2]);;
	return 0;
}

运行结果

好好学习,天天向上

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

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

相关文章

做跨境用哪种代理IP比较好?

代理IP对于做跨境的小伙伴来说&#xff0c;都是必不可少的工具&#xff0c;目前出海的玩法已经是多种多样&#xff0c;开店、账号注册、短视频运营、直播带货、网站SEO等等都是跨境人需要涉及到的业务。而国外代理IP的获取渠道非常多&#xff0c;那么做跨境到底应该用哪种代理I…

onnx 格式模型可视化工具

onnx 格式模型可视化工具 0. 引言1. 可视化工具2. 安装 Netron: Viewer for ONNX models 0. 引言 ONNX 是一种开放格式&#xff0c;用于表示机器学习模型。ONNX 定义了一组通用运算符&#xff08;机器学习和深度学习模型的构建基块&#xff09;和通用文件格式&#xff0c;使 A…

R语言绘图 | 带标签的火火火火火火火山图 | 标记感兴趣基因 | 代码注释 + 结果解读

在火山图中&#xff0c;我们有时候会想要标注出自己感兴趣的基因&#xff0c;这个时候该怎么嘞&#xff01; 还有还有&#xff0c;在添加标签时&#xff0c;可能会遇到元素过多或位置密集导致标签显示不全&#xff0c;或者虽然显示全了但显得密集杂乱&#xff0c;不易阅读的情况…

6.计算机网络

重要章节、考题比重大&#xff01; 主要议题&#xff1a; 1.网络分类 偶尔考 局域网&#xff1a;覆盖面较小&#xff0c;吞吐效率高&#xff0c;传输速度快&#xff0c;可靠性高&#xff1b; 广域网&#xff1a;传输距离较远&#xff0c;通过分组交换技术来实现&#xff1b…

【图论】树链剖分

本篇博客参考&#xff1a; 【洛谷日报#17】树链剖分详解Oi Wiki 树链剖分 文章目录 基本概念代码实现常见应用路径维护&#xff1a;求树上两点路径权值和路径维护&#xff1a;改变两点最短路径上的所有点的权值求最近公共祖先 基本概念 首先&#xff0c;树链剖分是什么呢&…

简单使用NSIS打包软件

NSIS是一个开源的打包工具. 官网: Download - NSIS (sourceforge.io) 使用这个编译 ​ 但是不建议使用这玩意写脚本,字体太难看了.我用vscode写的脚本,用这个编译的. ​ 写好脚本用这个软件打开, 然后选择这个编译,如果语法有错误 会编译不过,会提醒你哪一行不行,如果编译…

java的23种设计模式03-创建型模式02-抽象工厂方法

一、抽象工厂方法 1-1、抽象工厂方法的定义 抽象工厂模式是一个比较复杂的创建型模式。 抽象工厂模式和工厂方法不太一样&#xff0c;它要解决的问题比较复杂&#xff0c;不但工厂是抽象的&#xff0c;产品是抽象的&#xff0c;而且&#xff1a;有多个产品需要创建&#xff…

python中isinstance函数判断各种类型的小细节

1. 基本语法 isinstance(object, classinfo) Return true if the object argument is an instance of the classinfo argument, or of a (direct, indirect or virtual) subclass thereof. Also return true if classinfo is a type object (new-style class) and object is…

媒体播放器及媒体服务器软件Plex

什么是 Plex &#xff1f; Plex 是一套媒体播放器及媒体服务器软件&#xff0c;让用户整理在设备上的有声书、音乐、播客、图片和视频文件&#xff0c;并通过流式传输至移动设备、智能电视和电子媒体播放器上。Plex 可用于 Windows、Android、Linux、OS X和 FreeBSD。 在接触 N…

什么是IoT物联网平台?

在数字化浪潮的席卷下&#xff0c;物联网&#xff08;IoT&#xff09;技术逐渐渗透到我们生活的方方面面&#xff0c;从智能家居到智慧城市&#xff0c;从工业自动化到智能农业&#xff0c;IoT正以其独特的魅力改变着世界。然而&#xff0c;当我们谈论IoT时&#xff0c;我们究竟…

mysql timestamp有关于2038年的限制

1、改datetime当然是一了百了&#xff0c;但是如果需要设置default&#xff0c;则需要mysql版本在5.6及以上&#xff1b; alter table payment modify create_time datetime default CURRENT_TIMESTAMP null comment 创建时间; alter table payment modify update_time dateti…

嵌入式单片机学习思路感想分享

今天看到了一个提问,原话如下: 曾经干了8年单片机工程师,对工程师从入门,到入行,再到普通,再到高级,整个路径还算清晰,比如什么阶段,会碰到什么瓶颈,怎么突破,我都经历过。 这个同学,有个典型的问题,就是学得太多且杂了,估计稍微复杂点的项目,做不出来。 现在…

【Python循环3/5】条件循环语句

目录 导入 条件循环 边界条件 while循环 死循环 while循环与for循环的区别 总结 知识图谱 导入 我们已经学习了如何利用for语句实现代码重复执行的循环结构。通过遍历列表&#xff0c;输出其中的每一个元素。 for循环就像是排队办事&#xff0c;一个个进入&#xff0c;轮…

跨境电商应该用什么样的服务器?多大带宽?

跨境电商在选择服务器 和带宽时&#xff0c;需要考虑多个因素&#xff0c;包括业务规模、用户数量、网站流量、地理位置等。下面是一些关键考虑因素&#xff1a; 1、服务器类型 跨境电商通常会选择使用云服务器&#xff0c;因为云服务器具有灵活性、可扩展性和高可用性。云服务…

PTA L2-019 悄悄关注

新浪微博上有个“悄悄关注”&#xff0c;一个用户悄悄关注的人&#xff0c;不出现在这个用户的关注列表上&#xff0c;但系统会推送其悄悄关注的人发表的微博给该用户。现在我们来做一回网络侦探&#xff0c;根据某人的关注列表和其对其他用户的点赞情况&#xff0c;扒出有可能…

消息队列面试题

目录 1. 为什么使用消息队列 2. 消息队列的缺点 3. 消息队列如何选型&#xff1f; 4. 如何保证消息队列是高可用的 5. 如何保证消息不被重复消费&#xff08;见第二条&#xff09; 6. 如何保证消息的可靠性传输&#xff1f; 7. 如何保证消息的顺序性&#xff08;即消息幂…

腾讯云Kubernetes的容器服务平台TKE以及函数计算服务云感受

目录 一、整体结构 二、内容深度 三、技术实用性 一、容器技术 1. 腾讯自身 2. 美团 二、函数计算技术 1. 滴滴出行 2. 小红书 实际应用 容器技术实践示例 函数计算技术实践示例 高级技术探讨示例 书中感受 这边文章是对《2023腾讯云容器和函数计算技术实践精选集…

Linux中文件和目录管理(创建删除移动复制)

目录 1——一次建立一个或多个目录&#xff1a;mkdir ​2——创建一个空文件&#xff1a;touch 3——移动和重命名&#xff1a;mv 4——复制文件和目录&#xff1a;cp 5—— 删除目录和文件&#xff1a;rmdir和rm 在学习文件与目录的管理的一些命令之前&#xff0c;我们先…

LLM+Embedding构建问答系统的局限性及优化方案

LangChain LLM 方案的局限性&#xff1a;LLM意图识别准确性较低&#xff0c;交互链路长导致时间开销大&#xff1b;Embedding 不适合多词条聚合匹配等。 背景 在探索如何利用大型语言模型&#xff08;LLM&#xff09;构建知识问答系统的过程中&#xff0c;我们确定了两个核心…

集成学习 | 集成学习思想:Bagging思想

目录 一. Bagging思想1. Bagging 算法2. 随机森林(Random Forest)算法 在正文开始之前&#xff0c;我们先来聊一聊什么是集成学习&#xff1f; 集成学习是一种算法思想&#xff1a;将若干个弱学习器分组之后&#xff0c;产生一个新的学习器 弱学习器指预测误差在50%以下的学习器…