C语言中的指针专栏

一级指针

指针是什么
我们可以把宿舍楼里面的每一个同学看成一个个的变量,存放在一个个宿舍里,而为了方便找到每个同学,我们给每个宿舍标号,而指针就是每个宿舍的门牌号,它的值直接指向地址所对应的变量单元。
为什么要有指针
很明显我们找到一个个同学最快的方式就是通过宿舍门牌号,指针就是为了能找到以它为地址的内存单元。
总结:指针就是地址,指针变量就是变量,用来存放地址的变量(存放在指针里的值都会被当成地址来处理)。注意:一个int型变量占四个字节,每个字节都有一个地址,指针变量存放的是第一个地址。
代码说明:

#incude <stdio.h>
int main()
{
    int a=10;
    int *p=&a;
    return 0;
}

那么在这段代码里,a的地址就是存放在变量p中的,p就是一个指针变量。
指针的大小
指针的大小在32位平台上 是4个字节,在64位平台上是8个字节。
指针的解引用
指针就是它指向的目标

int main()
{
	int n = 0x11223344;
	char *pc = (char *)&n;
	int *pi = &n;
	*pc = 0x55;
	*pi = 0;
	return 0;
}

总结:指针的类型决定对指针解引用的权限。char的指针解引用就只能访问一个字节,而int的指针能访问四个字节。

指针±整数
一句话:指针±1是±其所指元素的类型大小。所以多级指针±1都是±4个字节,因为其所指类型都是指针。
下面来看一段代码:

#include<stdio.h>
#include<stdlib.h>

int main()
{
	int n = 10;
	char *pc = (char *)&n;
	int *pi = &n;

	printf("%p\n", &n);//1
	printf("%p\n", pc);//2
	printf("%p\n", pc+1);//3
	printf("%p\n", pi);//4
	printf("%p\n", pi+1);//5
	system("pause");
	return 0;
}

这里一共打印了五个变量,1、2、4不做过多解释,我们看到3和5都出现了指针+1,不同的是,3里pc指向的变量类型是char 类型,所以pc+1只+一个字节。而5里pi指向的变量类型是int 型,所以pi+1就+4个字节。
打印结果如下:
在这里插入图片描述
指针±指针
代表两个指针之间所经历的的元素个数
举一个例子:

int my_point(int a[10])
{
       int *p=&a[0];
       int *q=&a[9];
       retunr q-p;
}

很明显,这里指针p指向的是下标为0的第一个元素,q指向下标为9的第十个元素,所以q-p就是指针q和指针p之间所经历8的元素个数,为9.
同样,指针之间的运算还可以用来求字符串长度:

int my_strlen(char *a)
{
	char *p = a;
	while (*p != '\0')
	{
		p++;
	}
	return p-a;
}

二级指针

前面我们谈及的都是一级指针,我们知道指针变量也是变量,是变量就有地址,就可以被存放,二级指针就是用来存放指针的地址。
在这里插入图片描述
如上图所示,a的地址存放在pa中,pa的地址存放在ppa中,ppa就是一个二级指针。
二级指针解引用
*ppa就是访问pa。

int b=20;
*ppa=&b;//等价于 pa=&b
**ppa=30;
//等价于*pa=30;
//等价于a=30;

指针和数组

指针和数组本身是没有联系的。
数组名的概念
我们先看一段代码。

#include<stdio.h>
#include<stdlib.h>

int main()
{
	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
	printf("%p\n", arr);
	printf("%p\n", &arr[0]);
	system("pause");
	return 0;
}

在这里插入图片描述
由此可见,数组名和数组首元素的地址是一样的。数组名表示的就是数组首元素的地址。
那么再看下一段代码:

int arr[20]={1,2,3,4,5,6,7,8,9,0};
int *p=arr;

在这里p存放的是首元素的地址。那么我们可以使用指针来访问一个数组。

#include<stdio.h>
#include<stdlib.h>

int main()
{
	int arr[] = { 1,2,3,4,5,6,7,8,9,0 };
	int *p = arr;
	int sz = sizeof(arr) / sizeof(arr[0]);
	int i = 0;
	for (i = 0; i < sz; i++)
	{
		printf("&arr[%d]=%p   p+%d=%p\n", i, &arr[i], i, p + i);
	}
	system("pause");
	return 0;
}

在这里插入图片描述
很明显,&arr[i]和p+i结果是一样的。所以p+i其实计算的是数组的arr下标为i的地址。
那么我们现在直接通过指针来访问数组:

#include<stdio.h>
#include<stdlib.h>

int main()
{
	int arr[] = { 1,2,3,4,5,6,7,8,9,0 };
	int *p = arr;
	int sz = sizeof(arr) / sizeof(arr[0]);
	int i = 0;
	for (i = 0; i < sz; i++)
	{
		printf(" %d", *(p + i));
	}
	system("pause");
	return 0;
}

没有悬念,打印效果如下:
在这里插入图片描述

总结

指针也是一个变量,只不过和其他变量不同的原因是:其他变量放值,指针放地址。所以我们不要害怕指针,就和所有的变量一样处理就可以了。

发布了50 篇原创文章 · 获赞 30 · 访问量 9178

猜你喜欢

转载自blog.csdn.net/qq_42913794/article/details/90305511