详解指针1

  • Post author:
  • Post category:其他




1.指针与指针变量


– 为什么有指针?


我们知道一般计算机能做运算的元器件是CPU,而数据是保存在内存中的。当需要进行运算时,计算机需要将数据从内存拿到CPU的寄存器中。为了方便CPU可以直接在保存数据的内存中直接拿到数据于是引入了指针。


– 指针是什么?


指针就是地址。数据就保存在该地址的内存中。


– 什么是指针类型?


指针类型是一种新类型,它的表现形式为

类型+

*

常见的指针类型有:

int * //整形指针类型
char *//字符指针类型
float *//单精度浮点指针类型
double *//双精度浮点指针变量


– 什么是指针变量?


指针变量就是指针类型定义的变量。例如:

int *a=NULL;//定义一个整形指针变量 a
char *p=NULL;//定义一个字符指针变量 p


– 指针大小?


在32位平台下指针占4字节,在64位平台下指针占8字节。

原因:拿32位平台举例。在32位平台的计算机中连接CPU与内存有32根地址总线,每一根线有两态0和1,32根线两态的不同组合组成了内存的地址,所以在32位平台下内存有2^32次方=4GB大小。所以一个字节地址由32比特位组成,而一个直接由8比特位组成,所以一个地址占4字节,由于指针就是地址,所以指针占4字节。


注意:在32位平台下,所有类型指针占4字节。同理在64位平台下,所有类型指针占8字节。


在这里插入图片描述


– 指针类型作用?


由于指针的大小是确定,那为什么要定义指针类型呢?

下面列一个例子来展示。

#include<stdio.h>
int main(){
	int n = 10;
	char *pc = (char *)&n;//将n的地址强转为char *类型
	int *pi = &n;
	printf("%p\n", &n);
	printf("%p\n", pi);
	printf("%p\n", pc);
	printf("%p\n", pi+1);
	printf("%p\n", pc+1);
	return 0;

}

输出:

在这里插入图片描述

由上可知,int n占4字节,应该有4字节的地址。&n和指针取的地址为n的最小的地址,所以&n,pi和pc显示出来的地址相同。而我们发现pi+1和pc+1的地址是在原有的基础上加4和1,这就说明,

指针的类型决定了指针向前或者是向后的跨度

。跨度为sizeof(不带*类型)的大小。


– 指针解引用


对指针进行解引用代表指针存放的地址的目标。

int a=10;
int *p=&a;

此时的*p就是a。


注意: 指针进行解引用能操作几个字节也有指针类型决定。


如果定义一个int a将它的4字节全部写入数字,用一个整形指针类型的指针变量指向这个整形变量,对这个指针变量的解引用赋值时,这个整型变量4个字节都会发生改变,如果用一个字符指针类型的指针变量指向这个整形变量,对这个指针变量的解引用赋值,这个整型变量只有2个字节的发生变化。


– 指针的运算


主要讲指针的减法运算:前提必须是两个指针指向同一数组。

#include<stdio.h>
int main(){
	int n[5] = { 1, 2, 3, 4, 5 };
	int *ps = &n[4];
	int *pi = &n;//&n[0];
	printf("%d\n", ps - pi);
	return 0;

}

输出为

4

输出原因:当两指针相减结果为两指针之间元素个数。

解释:由于数组n为int,每个元素占4个字节。pi指向的是n[0]的最小地址,ps指向n[4]最小地址。pi与ps之间一共有16个字节,但是每个元素类型为int*占4个字节,所以显示为4.

在这里插入图片描述

将上面代码改一下类型发现:

#include<stdio.h>
int main(){
	int n[5] = { 1, 2, 3, 4, 5 };
	short *ps = &n[4];//将n的地址强转为short *类型
	short *pi = &n;
	printf("%d\n", ps - pi);
	return 0;

}

输出为:

8

由上知pi与ps之间有16字节,但是ps与pi被强转为short *类型使得每个元素占2字节。所以输出为8.


由上得出结论:在两指针指向同一数组的前提下,指针相减表示两指针之间的元素个数,具体元素个数由指针类型决定。



2.野指针


– 概念


野指针指指针指向的地址不可知(随机,不正确,没有明确限制)。


– 形成原因

  1. 指针未进行初始化
  2. 指针访问越界
  3. 指针指向的空间释放



3.指针和数组


指针与数组并没有关系,只是当一个指针指向一个数组时他们进行元素访问的方式相同。前提:数组类型与指针去*后的类型相同。

int a[3]={1,2,3};
int *p=a;//a数组首元素的地址。

此时就有:a[i]=*(a+i)=p[i]=*(p+i)。



4.二级指针

由于指针变量也是变量就需要开辟空间,就会有地址。而二级指针就是存放一级指针地址的指针。

表现形式:

int **a
char **b
float **c
...

形成格式为:类型+*+变量名。拿int **a举例-> 整形指针类型+*+a。

int a=10;
int *pa=&a;
int **ppa=&pa;
此时ppa存放的pa的地址,*ppa等于a的地址,**ppa等于a。



5.指针数组

指针数组实际上是数组,只是里面的元素都是指针。

表现形式:

int *a[5];
char *b[3]
float *c[2];
....



版权声明:本文为weixin_57023347原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。