C语言学习总结----指针

指针,指针变量,变量指针

指针: 内存单元的地址。
指针变量:存放地址(指针)的变量。
变量指针:变量的地址。
指针是一个无符号整数取值范围(0—2^32-1),由机器的寻址能力所决定,任何指针在32位机器平台下占4个字节,在64位平台下占8个字节,这个我们可以使用关键字sizeof(指针)来测试!
在这里插入图片描述

通常人们所讲的指针其实是指针变量,如定义一个指针,其实是定义一个指针变量。

为什么要有指针呢?

指针是C语言的灵魂!众所周知,数据是在内存中存放的,不同类型的数据所占字节数的多少不同,为了正确地访问这些数据,因此为每个字节都编上号码,就像门牌号、身份证号一样,每个字节的编号是唯一的,根据编号可以准确地找到某个字节。简单来讲指针的作用就是快速准确定位和查找!

常见的指针类型

字符指针:两种用法:
1.单个字符的地址

int main()
{
	char ch = 'h';
	char* pch = &ch;
	return 0;
}

2.字符串首元素的地址

int main()
{
	char* str = "hello";//str中保存的是首元素h的地址
	return 0;
}

二级指针 (指针的指针)

int main()
{
	int a = 3;
	int* pa = &a;    //一级指针
	int** ppa = &pa; //二级指针
	return 0;
}

在这里插入图片描述
注:有二级指针自然也有三级指针,四级指针,把这些指针统称为多级指针!

指针常量与常量指针

指针常量:指针类型的常量。本质是一个常量,指针的值不能被修改,但指针指向的对象的内容可以被修改。

int main()
{
	int a = 3;
	int b = 1;
	int* const p = &a;
	*p = 5;    //正确,p是一个常量,但*p不是,可以作为左值
	p = &b;    //错误,左值不能是常量,或者说p是常量值不能被修改
	return 0;
}

常量指针:指向常量的指针。本质是一个指针,指针的值可以被修改,但指针指向的对象的内容不能被修改。

int main()
{
	int a = 3;
	int b = 1;
	int const *p = &a;
	*p = 5;    //错误,*p是一个常量,不能写入
	p = &b;    //正确
	return 0;
}

当两者同时被const修饰呢?正如所料,p和*p的值都不能被更改!

int main()
{
	int a = 3;
	int b = 1;
	int const * const p = &a;
	*p = 5;    //错误,*p是一个常量,不能写入
	p = &b;    //错误,p也是一个常量
	return 0;
}

如何区分呢?
主要看const修饰的是谁!简便方法:去掉类型和变量名 将const读作常量,*读作指针就OK了!
小问题:数组名属于哪一个呢?

数组指针和指针数组

数组指针:本质是一个指针,不过是指向一个数组的指针!大小自然也是4个字节!
指针数组:本质是一个数组:数组的每一个元素都是指针类型,这里的指针类型指的是同一种指针类型,毕竟数组是同一种类型元素的集合体!
int main()
{
	int *p1[10];
	int(*p2)[10];
	return 0;
}

上面哪个是数组指针呢?
当然是int(* p2)[10];原因是这样的,虽然下标引用操作符的优先级高于解引用,但是()使得p2先和 结合使得p2成为一个指针,并且这个指针指向一个含有十个整型元素的数组。因此它是一个数组指针。
int
p2[10]呢?它是一个指针数组,首先p2先和[]结合使得其成为一个数组,数组中的每个元素的类型都是int*类型的,因此它是一个指针数组!

指针运算

算术运算:对指针进行加一或减一操作可不是 简单的进行加一或者减一。对指针加一,其实加的是其指向的类型的大小,如给整型指针加一等于加四,给字符型指针加一等于加一,给数组指针加一,等于加一个数组的大小…
在这里插入图片描述

arr为数组名,是数组首元素的地址,即是一个整型指针,因此它加一等于加四,即指向arr[1],&arr是整个数组的地址,即是一个数组指针,因此它加一等于加sizeof(arr)=20,所以它直接越过整个数组的大小,指向下一个数组的首元素。
指针减指针只有当两个指针同时指向同一个数组时,才允许指针减指针,减去的结果是一个有符号整数,代表两个指针之间元素的个数。
在这里插入图片描述
关系运算:指针可以进行的关系运算有< <= == >= !=
注:关系运算得前提是两个指针指向同一个数组,否则计算是没有任何意义的!

int main()
{
	int arr[5];
	int* p = arr;
	for (; p < &arr[5]; p++)
	{
		*p = 0;
	}
	return 0;
}
int main()
{
	int arr[5];
	int* p = arr+4;
	for (; p >= &arr[0];p--)
	{
		*p = 0;
	}
	return 0;
}

其实第二段代码存在一个问题,标准规定,指向数组的指针可以与指向数组最后一个元素后面的第一个位置的内存的指针相比较,但不允许与其首元素前面的内存空间的指针相比较!

猜你喜欢

转载自blog.csdn.net/weixin_43213517/article/details/84194604