C语言—浅析指针

目录

指针

一、什么叫做指针?

二、指针的类型

        1.一级指针

        2.二级指针

        3.数组指针

        4.函数指针

        5.野指针

 三、指针的运算

        1.指针的赋值

        2.指针的移动

        3.指针-指针


指针

一、什么叫做指针?

        指针是用来存放内存地址的变量,可以简单的理解为,指针就是地址,平时所说的指针通常都是说的指针变量。

        举个例子,定义一个整形变量并初始化:

int a = 20;
int *p = &a;

        此时我们就说指针变量p指向了a内存的地址,如果通过解引用(*)操作,则会得出这块内存中存储的值为20,这里要注意区分内存地址和内存储存了什么是两块不同的空间,地址在32位机器上只占4个字节,在64位机器上占8个字节。

        和其他变量一样,指针也可以进行初始化,初始化如下:

int *p = NULL;

二、指针的类型

       指针大致可以分为以下几种类型:

        1.一级指针

        一级指针就是我们常见的普通指针,例如上述的一个定义指针的例子,就是一个一级指针,除了int型的一级指针之外,还有其他常见的一级指针。

char  *pc = NULL;
int   *pi = NULL;
short *ps = NULL;
long  *pl = NULL;
float *pf = NULL;
double *pd = NULL;

        2.二级指针

        二级指针指的是指向一级指针的指针,里面存储的是一级指针的地址,通过*解引用操作可以找到一级指针中存放的内容,二次解引用**可以找到一级指针指向的地址的内容,如下,便是一个二级指针,输出为10

int a = 10;
int *p = &a;
int **pa = &p;
printf("%d",**pa);

        3.数组指针

        数组指针,就是指向数组的指针,里面存放的是一维数组的地址其中一种形式如下:

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

        我们就说*p是一个数组指针,指向的数组拥有十个元素,每个元素类型是int类型,这里需要注意的是,如果写成int *p[10] = arr(去掉括号),则会变成一个指针数组而不是数组指针,因为[ ]的优先级高于*,所以p先和右边的[ ]相结合了

        4.函数指针

        该指针指向的是一个函数的地址,如下便是一个函数指针为:

void (*p)();

        5.野指针

        概念:野指针是指指针指向的内存地址是未知的(随机、不正确、没有明确限制的都算未知)

        既然知道了什么是野指针,那么有哪些操作容易产生野指针呢?

        1.对指针定义时未进行初始化,指针变量刚被创建时不会自动成为NULL指针,它的缺省值是随机的,它所指的空间是随机的。

int main()
{
	int * p;
	*p = 10;
	return 0;
}

        2.指针越界访问:指针指向的范围超出了合理范围,或者调用函数时返回指向栈内存的指针或引用,因为栈内存在函数结束时会被释放。

int main()
{
	int arr[10] = {0};
	int *p = arr;
	for(int i = 0; i <= 11; i++)
	{
		*(P++) = i;//当i=11时,指针指向的范围超出数组arr的范围,p变成野指针。
	}
	return 0;
}

        3.指针释放后未置空:有时指针在free或delete后未赋值 NULL,便会使人以为是合法的。其实它们只是把指针所指的内存给释放掉,但并没有把指针本身忘记。此时指针指向的就是无效内存

int main()
{
	int *p = NULL;
	p = malloc(10 * sizeof(int));//malloc函数为开辟内存
	if (!p)
	{
		return;
	}
	
	free(p);//释放了内存,故要马上给p赋值为空指针NULL
	p = NULL;
	return 0;
}

        所以要避免成为野指针,就应当尽量多的避免上述三种操作

 三、指针的运算

        1.指针的赋值

        指针的赋值通常有如下形式:

        指针变量=&变量
        指针变量=指针变量
        指针变量=NULL

        2.指针的移动

        指针的移动通常为指针±整数,在下面的例子中,每一次循环,指针p将跳到下一个地址,因为这里是int类型的数组,所以将跳过四个字节(关于指针移动到底跳过多少个字节,笔者会在之后再做总结,这里不在叙述)

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

        3.指针-指针

        得到的是指针之间的元素个数

        最后,这是笔者的第一篇博客,水平有限,如有解析不到之处请各位多多批评指正

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值