指针与数组

Posted 张同学吧

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了指针与数组相关的知识,希望对你有一定的参考价值。

指针和数组的关系

通过上一篇文章指针的原理——地址、内存我们知道,数组名表示的其实是数组首元素的地址,所以我们可以这样来写代码

#int arr[5]={1,2,3,4,5};
int *p=arr;//p存放的就是1的地址

所以我们就可以通过指针来访问数组了,

#include<stdio.h>
int main()
{
	int arr[5]={1,2,3,4,5};
	int *p=arr;
	int len=sizeof(arr)/sizeof(arr[0]);//求数组长度
	for(int i=0;i<len;i++)
	{
		printf("&arr[%d]=%p==>p+%p\\n,i,p,p+i);
	}
	return 0;
}

在这里插入图片描述
所以*(p+i)其实等于arr[i]

二级指针

既然指针也同为变量,是变量就有地址,所以我们也可以用二级指针指向指针来存放一级指针的地址。
在这里插入图片描述
从上面我们可以看出a的地址存放在p中,p的地址存放在pp中,p是一级指针,pp是二级指针。我们也可以通过二级指针来修改a的值**pp=10;其实就是通过*pp找到p,再对p进行解引用找到a。

指针数组与数组指针

指针数组的定义

在C语言和C++等语言中,数组元素全为指针变量的数组称为指针数组,指针数组中的元素都必须具有相同的存储类型、指向相同数据类型的指针变量。指针数组比较适合用来指向若干个字符串,使字符串处理更加方便、灵活。一维指针数组的定义形式为:“类型名
*数组标识符[数组长度]”。

如果指针数组在存放数组时,我觉得你可以把指针数组抽象成一个二维数组。

#include<stdio.h>
int main() {
	int arr1[4] = { 1,2,3,4 };
	int arr2[4] = { 11,21,31,41 };
	int arr3[4] = { 12,22,32,42 };
	int* arr[3] = { arr1,arr2,arr3 };
	printf("%d\\n", *arr);
	printf("%d\\n", &arr1);
	int num = 0;
	int i = 0;
	while (num < 3) {
		printf("arr%dΪ:{", num + 1);
		for (int i = 0; i < 4; i++) {
			printf(" %d ", *(*(arr + num) + i));//*(arr +num)分别是arr1的首地址元素,arr2的首地址元素,arr3的首地址元素
		}
		printf("}\\n");
		num++;
	}
	return 0;
}

在arr[3]中,每一个变量都是整形指针,指向的分别是arr1首元素的地址,arr2首元素的地址,arr3首元素的地址。所以我们可以通过数组指针来访问数组中的元素,形似二维数组。
在这里插入图片描述

数组指针的定义

数组指针,指的是数组名的指针,即数组首元素地址的指针。即是指向数组的指针。例:int (*p)[10];
p即为指向数组的指针,又称数组指针。

[]优先级大于*,故数组指针声明时要加()。首先说明p是一个指针,指向一个整型的一维数组,这个一维数组的长度是n,也可以说是p的步长。也就是说执行p+1时,p要跨过n个整型数据的长度。比如它指向包含5个int元素的一维数组a[3][4]时,此时p的增量以它所指向的一维数组长度为单位:int (*p)[4]=a;

数组指针指向一维数组

#include<stdio.h>
#include<stdlib.h>
void main()
{
    //数组指针的用法,用处。
    int b[16]={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16};
    int (*p)[4]; //该语句是定义一个数组指针,指针步长为4个int即16位。
    //int *p2=b;
    p=b;
    int i=0;
    while(i<16)
    {
          printf("%d\\t",(*p)[i]);
          //printf("%d\\t",*p2++);
          i++;
    }
}

但是你如果想指向一维数组,直接用指针变量就🆗,比这简单得多。

数组指针指向二维数组

#include<stdio.h>
#include<stdlib.h>
void main()
{
    int a[3][4]={{1,2,3,4},{11,12,13,14},{21,22,23,24}};
    int (*p)[4]; //该语句是定义一个数组指针,指针步长为4个int即16位。
    p=a;
    int i=0;
    while(i<3)
    {
        printf("%d\\t",(*p)[i]);
        *(p+2)+3表示a[2][3]地址(第一行为0行,第一列为0列),**(p+2)+3)表示a[2][3]的值。
        //数组指针,指向的是一个数组整体,相当于指针也带了下标,当执行i++操作时,下标+1,得到该数组的下一个元素,
        //在该例中,指针没有位移,所以依次输出为1 2 3
        printf("%d\\t",(*p++)[0]);
        *(p+i)是一维数组a[i][0]的地址;
        //整型数组类型的指针,指向的是一个数组整体,当执行*p++操作时,指针位移该数组长度的位数
        //在该例中,即指针位移4个int的长度,所以输出是1 11 21
        i++;
    }
}

所以数组指针也称指向一维数组的指针,亦称行指针。
总结:数组指针只是一个指针变量,似乎是C语言里专门用来指向二维数组的,它占有内存中一个指针的存储空间。指针数组是多个指针变量,以数组形式存在内存当中,占有多个指针的存储空间。

举例

数组指针:

#include<stdio.h>
int main()
{
	char c[][4] = {"哥", "哥", "我", "岸", "上", "走"};    //UTF-8:一个汉字=3个字节
	char (*p)[4];
	int i;    
	p=c;    //将指针定位于c[0]
	for(i=0;i<=5;i++)
	{
		printf("%s, ", *(p+i));  //或者将*(p+i)替换成*p++
	}
	printf("\\n");    
	for(i=5;i>=0;i--)
	{    
		printf("%s,",*(p+i));    //或者将*(p+i)替换成*--p
	}   
	return 0;
}
指针数组:

#include<stdio.h>
int main()
{
	int i;
	char *pch[6] = {"妹","妹","你","坐","船","头"};
	for(i=0;i<6;i++)
	{
		printf("%s, ",pch[i]); 
	} 
	printf("\\n");     
	for(i=5; i>=0; i--)
	{ 
		printf("%s\\n",pch[i]); 
    }
	return 0;
}

以上是关于指针与数组的主要内容,如果未能解决你的问题,请参考以下文章

在第6731次释放指针后双重免费或损坏

指针与数组

指针与数组

Go语言切片

指针与一维数组和二维数组以及字符串指针数组的学习笔记

c语言中如何通过二级指针来操作二维数组