栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

C语言指针详解(1)

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

C语言指针详解(1)

.指针详解   

    之前我说过一篇关于指针在C语言中的基本使用,这次我再来细讲一下指针的其他内容。

目录

一.指针详解

1.指针定义

2.指针类型

3.野指针

4.如何规避野指针?


1.指针定义

指针理解的2个要点:

1. 指针是内存中一个最小单元的编号,也就是地址。

2. 平时我们所说的指针,通常指的是指针变量,是用来存放内存地址的变量。

int main(){
int a=10;
int* pa=&a;    //取出a的地址关联给指针变量
*pa=20;        //解引用操作,间接改变变量的值
printf("%dn",a);//20
return 0;
}

        *pa-->0x0012FF40,指针指向的就是变量a的起始地址。 

         内存会被划分成一个个小小的存储单元,每个内存单元的大小都是固定为1字节(byte)大小。经过大量的计算和权衡,一个存储单元对应一个地址,对于32位的机器,假设有32根地址线,那么假设每根地址线在寻址的时候产生高电平(高电压)和低电 平(低电压)就是(1或者0); 那么32根地址线产生的地址就会是:

00000000000000000000000000000000(32bit位全0)

................................................................        到

1111111111111111111111111111111111111(32bit全1)

共有2^32次方个地址,换算成大单位的话,一块内存大概有4GB的大小。而对于64位系统,则共有2^64次方个地址,约8GB内存。

        总结: 指针是用来存放地址的,地址是唯一标示一块地址空间的。

                    任何指针的大小在32位平台是4个字节,在64位平台是8个字节 。

 

2.指针类型

        C语言中,变量与数组有整数类型,浮点类型,字符类型等,指针也是一样的。

           char* 类型的指针是为了存放 char 类型变量的地址。

           short* 类型的指针是为了存放 short 类型变量的地址。

           int* 类型的指针是为了存放 int 类型变量的地址。 

                .....

        刚才讲到了 任何指针的大小都为4字节(32位中),指针不会因为类型的不同而改变其字节大小,那么指针类型到底有怎样的意义?

a.指针类型意义1:指针变量的解引用 

# include
int main() {
	int a = 0x11223344;//地址都是用十六进制表示(0x为16进制表示形式)
	int* p = &a;
	*p = 0;
	printf("%pn", a);
	return 0;
}

 

 

        在上面的代码中,我将a的地址设置为了0x11223344,使用指针变量关联了a的地址,通过解引用的操作,令指针p将a的值间接化为0,通过调试,可以发现下图中a的地址改为了0x00000000。

 

        十六进制地址中,每两位代表一个字节,所以地址共有4字节大小,而int类型的指针解引用后便可以访问到四字节的地址数,从而将变量a的地址全部换为0。

 

        而char型指针在关联整型变量地址的过程中,指针解引用为0, 也只是改变了变量a地址的一个字节,其他三个字节不变。

        我讲解的这两个例子是为了展示指针的访问权限作用:

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

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

 

b.指针类型意义2.指针的加减操作 

int main(){
        int n = 10;
		char* pn = (char*)&n;
		int* pm = &n;

		printf("%pn", &n);
		printf("%pn", pn);
		printf("%pn", pn + 1);
		printf("-----n");
		printf("%pn", pm);
		printf("%pn", pm + 1);
	
	return 0;
}

        上图代码中, 创建了两种类型的指针变量去接收同一个变量的地址,通过对两种指针变量+1,产生的结果也是不同。如下图

 

 

总结:指针的类型决定了指针向前或者向后走一步有多大(距离)。 

            以上两种方式展现出来的就是指针类型的真正意义所在!

 


3.野指针

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

        野指针用来做比喻的话,其实可以看作一只脾气暴躁的狗,无人管教驯服所以很危险,若不靠近则相安无事,若进行接触或者挑逗它,它就会咬伤我们。

        而在C语言中,指针也好比是这样,若不加以初始化给其赋值,它就会产生错误的程序乱码。

int main()
		{
			int* p;
			*p = 10;//非法访问内存了,这里的p就是野指针
			return 0;
		}

        如图代码中指针p没有初始化,就意味着没有明确的指向。一个局部变量不初始化的化,放的是随机值(默认):0xcccccccc
        

        例如在指针作数组遍历访问时,也会遇到野指针的情况

#include 
int main()
{
    int arr[10] = {0};
    int *p = arr;
    int i = 0;
    for(i=0; i<=11; i++)
   {
        *(p++) = i;
   }
    return 0;
}

        如图,数组大小为10,但循环却经历了11次,那么第十一次的循环中 ,当指针指向的范围超出数组arr的范围时,p就是野指针。

 

         注意小贴士:数组允许越界,但不允许使用

 

例2.指针指向的空间已释放。

int* test()
		{
			int a = 10;
			return &a;
		}
		
		int main()
		{
			int*p = test();
			*p = 20;
			return 0;
		}

       这段代码的意思是: 从主函数开始后,通过调用test函数,将a的地址传给指针p,将p解引用后修改a的值。

        但我们知道函数中的局部变量一出函数就会被销毁,所以一调用完函数指针P指向的那块空间就已经没了,指针虽然还保留着那块空间的地址,但已经不属于它了,要是继续访问就是非法的,从而指针P就成了野指针。

 

 

4.如何规避野指针?

1.创建指针的同时就顺带初始化操作

int a=10;

int*p=&a;

若不知道将指针*p指向谁,就先设成空指针

int *p=NULL; 

2.小心指针越界情况,务必注意循环次数 。

3.指针使用前检查其有效性。

4.若指针空间被释放,将指针置成NULL。

                                                                                                                打完收工!

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1022874.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号