首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >C语言: 指针

C语言: 指针

作者头像
青衫哥
发布2023-03-31 09:01:56
发布2023-03-31 09:01:56
2.4K00
代码可运行
举报
文章被收录于专栏:C++打怪之路C++打怪之路
运行总次数:0
代码可运行

目录

概念:

指针的类型

指针的解引用

野指针

野指针的成因

空指针

指针与数组

指针在数组中的使用:

二级指针


概念:

在计算机科学中,指针(Pointer)是编程语言中的一个对象,利用地址,它的值直接指向

(points to)存在电脑存储器中另一个地方的值。由于通过地址能找到所需的变量单元,可以

说,地址指向该变量单元。因此,将地址形象化的称为“指针”。意思是通过它能找到以它为地址

的内存单元。

总的来说,指针就是变量,用来存放地址的变量。

代码语言:javascript
代码运行次数:0
运行
复制
#include <stdio.h>
int main()
{
 int a = 10;//在内存中开辟一块空间
 int *p = &a;//这里我们对变量a,取出它的地址,可以使用&操作符。
   //将a的地址存放在p变量中,p就是一个之指针变量。
 return 0; }

那么一个变量单元该是多大呢?

可以知道, 对于 32 位的机器,假设有 32 根地址线,那么假设每根地址线在寻址的是产生一个电信号正电 / 负电( 1 或者0 ),可以控制的内存大小为2^32个单元大小,如果是一个比特位大小,那么能够控制的内存空间为512兆,也就是0.5个g,这显然是不合理的。

因此,一个单元大小是一个字节比较合理,能控制的内存为4g左右。同样,64位的机器更大。

所以,一个指针在32位的情况下,我们就得用4个字节大小才能控制到全部的地址。

当然,在64位系统下,得要8个字节

指针的类型

代码语言:javascript
代码运行次数:0
运行
复制
char  *pc = NULL;
int   *pi = NULL;
short *ps = NULL;
long  *pl = NULL;
float *pf = NULL;
double *pd = NULL;

指针的定义方式为:类型+*+名称。

指针的类型与指向的目标的类型一致,指针指向的是目标的地址。

例如:

代码语言:javascript
代码运行次数:0
运行
复制
int a=10;
int* p=&a;

总结: 指针的类型决定了,对指针解引用的时候有多大的权限(能操作几个字节)。 比如: char* 的

指针解引用就只能访问一个字节,而 int* 的指针的解引用就能访问四个字节。

指针的解引用

如果我们想要获取指针指向的地址存放的数据,我们就要用到解引用

例如:

代码语言:javascript
代码运行次数:0
运行
复制
int a=10;
int*p =&a;
printf("%d\n",*p);

这样,打印的才是a的值,否则,获取的就是该变量的地址。

野指针

概念: 野指针就是指针指向的位置是不可知的(随机的、不正确的、没有明确限制的)指针变量

在定义时如果未初始化,其值是随机的,指针变量的值是别的变量的地址,意味着指针指向了一

个地址是不确定的变量,此时去解引用就是去访问了一个不确定的地址,所以结果是不可知的。

野指针的成因

1、创建指针未初始化

代码语言:javascript
代码运行次数:0
运行
复制
#include <stdio.h>
int main()
{ 
 int *p;//局部变量指针未初始化,默认为随机值
    *p = 20;
 return 0; }

2、指针越界访问

代码语言:javascript
代码运行次数:0
运行
复制
#include <stdio.h>
int main()
{
	int arr[2] = { 1,2 };
	int* p = arr[3];
	printf("%d\n", *p);
	return 0;
}

当访问超过数组的范围时,p就是野指针。

 3、指针的空间释放掉了

那么,如何有效的规避野指针呢?

1、指针初始化 

2、小心越界访问

3、指针指向的空间释放

4、使用之前检查有效性

空指针

即是将指针置空

代码语言:javascript
代码运行次数:0
运行
复制
int* p = NULL;

指针与数组

代码语言:javascript
代码运行次数:0
运行
复制
#include <stdio.h>
int main()
{
	int arr[2] = { 1,2 };
	printf("%p\n", arr);
	printf("%p\n", &arr[0]);
	return 0;
}

结果:

 可以看到,数组名指向的就是第一个元素的地址。

指针在数组中的使用:

代码语言:javascript
代码运行次数:0
运行
复制
#include <stdio.h>
int main()
{
	int arr[2] = { 1,2 };
	int* p = arr;
	for (int i = 0; i < 2; i++)
	{
		printf("%d\n", *(p + i));
	}
	return 0;
}

这里我们可以看出,*(p+i)就是数组下标为i的元素。

二级指针

实例:

代码语言:javascript
代码运行次数:0
运行
复制
#include <stdio.h>
int main()
{
	int arr[2] = { 1,2 };
	int* p = arr;
	int** p = &p;
	return 0;
}

指针指向的是目标变量的地址,那么二级指针指向的就是指针的地址。

同样的,如果要获取指针指向的内容,要使用双重解引用 ** 

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-04-10,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 概念:
  • 指针的类型
  • 指针的解引用
  • 野指针
    • 野指针的成因
  • 空指针
  • 指针与数组
    • 指针在数组中的使用:
  • 二级指针
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档