指针内容全覆盖(这可能是你看到过的最全面的讲解)

上两期内容我们已经为大家把指针的基本内容介绍完毕,本期内容将会对指针进行进阶讲解

目录

一、字符指针

二、&数组名和数组名(以及若干补充)

三、指针和二维数组

 


一、字符指针

在指针的类型中我们知道有一种可以指向字符的指针叫做字符指针char*

接下来我们看该指针的一般使用方式


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

我们通过一个字符指针对一个字符的内容进行了修改

接下来请大家看另外一种使用方法

#include<stdio.h>
int main()
{
	char*p="hello";
	printf("%s",p);
	return 0; 
}

需要我们注意的就是此时的p中存放的是我们这一段字符的首字母地址

明白了以上内容之后我们来看一下这段代码。


#include<stdio.h>
int main()
{
	char ch1[]="hello";
	char ch2[]="hello";
	char *pc1="hello";
	char *pc2="hello";
	if(ch1==ch2)
	printf("ch1和ch2相等\n"); 
	else
	printf("不相等\n");
	if(pc1==pc2)
	printf("YES\n");
	else
	printf("NO");
	return 0;
}

 我们看到输出的结果表明ch1和ch2是不相等的,但是pc1和pc2是相等的,这是为什么呢?

我们知道数组名表示的是首元素地址,所以ch1和ch2分别表示两个数组的首元素地址,那么都表示h的地址为什么不一样呢?

我们知道,当我们定义好一个数组之后,计算机就会在内部为其开辟一块空间来存放数组的内容,所以ch1和ch2作为两个数组,计算机就为他们各自开辟了一个空间,这两个空间的首元素地址自然是不会相等的

接下来我们看pc1和pc2这两个指针表示的是hello这个字符的首元素地址,字符是同样的在计算机内部就只有一块空间来存放这个字符串,当然他们应该是相等的。

看到这里你是否明白了呢?

二、&数组名和数组名(以及若干补充)

在c语言中&作为取地址符号自然可以取出变量的地址,那么我们同样也知道数组名也表示地址那么这两者之间有什么不同呢?

#include<stdio.h>
int main()
{
	int arr[10]={0};
	printf("%p\n",arr);
	printf("%p\n",&arr);
	return 0;
}

 根据输出结果来看两者之间好像没有什么区别,但是事实果真如此吗?

#include<stdio.h>
int main()
{
	int arr[10]={0};
	printf("%p\n",arr);
	printf("%p\n",&arr); 
	printf("%p\n",arr+1);
	printf("%p\n",&arr+1);
	return 0;
}

我们再看这样一段代码,如果他们两个没有区别的话此时的输出结果应该都相等,

可是输出结果出现了不同,说明两者之间是不同的

这里我们需要注意的是&arr取到的是整个数组的地址,而arr只表示首元素地址,当&arr+1时表示在整个数组地址的基础上加1即跨过一个数组的长度, 

 我们不妨看一下两者之间的差距是36,正好是9个int型数据的大小,看到这里你明白了吗?

通过上文的一些讲解希望大家可以明白&数组名表示整个数组的地址,

同样sizeof如果括号里面是数组名的话也计算的是整个数组的大小,

三、指针和二维数组

在之前我们为大家介绍过指针和数组,但只是简单的对一维数组和指针的关系介绍,今天我们为大家介绍指针和二维数组的关系。

#include<stdio.h>
int main()
{
	int a[3][3]={1,2,3,4,5,6,7,8,9};
	int (*p)[3]=a;
	for(int i=0;i<3;i++)
	{
		for(int j=0;j<3;j++)
		{
			printf("%2d",a[i][j]);
		}
		printf("\n");
	}
	for(int i=0;i<3;i++)
	{
		for(int j=0;j<3;j++)
		printf("%2d",*(*(p+i)+j));
	printf("\n");
	}
	return 0;
}

因为我们此处使用的是二维数组指针无法直接指向二维数组,所以我们此处使用数组指针

定义了一个指向含有三个整型变量的数组的指针

此时我们可以把a[3][3]抽象理解成为一个一维数组,数组名是a[3]这个数组中有三个元素,每个元素是一个一维数组 

p表示这个抽象的一维数组的首元素地址

 我们对这个二维数组进行遍历操作并且输出结果

同时我们对该指针变量也进行遍历,p是一个指向数组的指针p+i表示的是数组中的第i个元素,因为我们已经把二维数组抽象为一个一维数组,所以p+i表示的就是抽象成为的一维数组中的第i个元素,因为抽象的一维数组中第i个元素表示的也是一个数组,所以我们此时得到的就是二维数组中的第i行元素

对第i行进行解引用我们就进入该行中再加j是我们找到i行中第j个元素的地址,解引用得到第i行第j列个元素。

所以*(*(p+i)+j)表示的就是二维数组中第i行第j列的元素。

本篇文章到此结束,谢谢大家!

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值