关于指针的一些总结性问题

        下面的例子都是有利于理解指针的运用的。我之前就总结过,但是没有形成博客。直到昨天,我在写一个平衡二叉树的插入的时候,发现自己对于指针的运用还是不特别熟悉,所以决定总结一下,以便之后更好的编程。尤其是写有关树的代码,真的是避不开指针。困难只有克服,今天你逃避了,迟早有一天你又会遇到他的。
        关于测试点3,至于会不会出现这个bug,我在几个编译器上面都没有测试出来。但是我还是认为会出现这样的问题,所以如果大家有自己的看法,欢迎评论区讨论!!!

// Demo_3.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include"pch.h"
#include<stdio.h>
#include<stdlib.h>

//第一个测试
/*
void fun(int *p)
{
	*p = 3;
}
int main()
{
	int a = 10;
	//自己可以画一个内存四区图来分析这个问题
	//此时函数fun()函数应该要改变a的值
	fun(&a);
	printf("%d", a);
	return 0;
}
*/

//第二个测试
/*
void fun(int *p)
{
	*p = 3;
}
int main()
{
	int a = 10;
	int *q = &a;
	fun(q);
	printf("%d\n", a);
	fun(&a);
	printf("%d\n", a);
	//通过画内存四区图分析,a的值的确已经被改变了,但是q的值是没有改变的
	//什么意思呢?就是说,fun()函数没有改变q的值,它的值还是原来a的地址。
	//因为a的地址上面的值被改变了,所以*q的值也就被改变了。但是q的值是没有
	//改变的。这里我称*q的值为“超值”,而q的值就是“值”
	printf("%d", *q);
	return 0;
}
*/


//第三个测试
/*
void fun(int *p)
{
	int a = 9;
	p = &a;
}
int main()
{
	int a = 10;
	int *q = &a;
	//这里其实是有一个隐藏的bug的。因为在fun()函数中,,int a=9就是一个局部变量
	//当fun()函数返回的时候,就会导致其实那里的内存就是一个不可知的内存。但是这个
	//不一定会输出“烫烫烫”,因为可能在你输出的时候并没有释放内存给别人使用。
	//***:我认为就是在一个函数中进行指针的赋值,你要保证的你得地址是一个堆内存
	//地址才好。这样子就就不会出现你的指针指向的是一个被释放的内存空间。
	fun(q);
	int b = 10;
	printf("%d", *q);
	return 0;
}
*/


//第四个测试
/*
void fun(int **p)
{
	int *q = (int*)malloc(sizeof(int));
	*q = 50;
	*p = q;
}
void fun1(int *p)
{
	int *q = (int*)malloc(sizeof(int));
	*q = 50;
	p = q;
}
int main()
{
	int *q = NULL;
	//我写这个测试原因就在于提出一个结论:“你要想通过函数来改变指针的值(注意,
	//不是超值,仅仅是指针的值),那么就一定要通过指针的指针来改变这个指针的值。”
	//这个问题就在你大二的时候出现过,其实这个也是可以通过画内存四区图来看出的。
	fun(&q);
	//fun1(q);
	printf("%d", *q);
	return 0;
}
*/

//第五个测试
/*
typedef struct Node
{
	int data;
	struct Node *lchild;
	struct Node *rchild;
}Node;

void fun(Node *node)
{
	node->data = 50;
	node->lchild = (Node*)malloc(sizeof(Node));
	node->rchild = (Node*)malloc(sizeof(Node));
}

int main()
{
	//这里例子我想要说明的就是野指针的问题。也就是说:对于node来说,他现在没有一个
	//具体的指向,或者说指向的是NULL。那么你调用fun()函数的时候,就会导致程序去向
	//地址0的位置写入50,然后在地址0后4个字节的位置写入一个malloc()函数分配的地址
	//因为地址0是操作系统保护的位置,所以是不能被用户的程序写入数据的。
	//Node *node = NULL;
	Node *node = (Node*)malloc(sizeof(Node));
	fun(node);
	return 0;
}
*/
//我先介绍几个我自己的定义,有利于后面概念的理解:
//1.指针的附加值:因为有的指针是一个结构体的指针,例如Node *node。那么node->data就是
//指针node的附加值
//2.指针的原始值:这个就是指针的值,也可以说是指针的指向。int *p=&a;那么指针p的值
//就是&a
//前面说过,你想要通过函数改变指针的值,就要使用指针的指针。但是如果你想要改变的是
//指针的附加值,例如node->lchild,那么其实就可以通过指针Node *node的来改变。这个
//也是可以通过画内存四区图得出的。这个也是你在写一些树的代码的时候,你应该深有体会
//但是如果你想要通过指针的指针来改变也是可以的。下面我就使用这样的一个例子,同时解决
//上面的野指针的问题

//第六个测试
/*
typedef struct Node
{
	int data;
	struct Node *lchild;
	struct Node *rchild;
}Node;

void fun(Node **node)
{
	*node = (Node*)malloc(sizeof(Node));
	(*node)->data = 50;
	(*node)->lchild = (Node*)malloc(sizeof(Node));
	(*node)->rchild = (Node*)malloc(sizeof(Node));
}

int main()
{

	Node *node = NULL;
	//fun()函数中使用了一个指针的指针来改变node->lchild和node->rchild。但是这个仅仅
	//是这个函数的附加效果,主要的原因,就是为了给node赋值。因为我现在想要改变指针
	//node的值,并且是通过函数来改变,所以仅仅只能使用指针的指针才能达到改变实参node
	//的效果。这个也是可以通过画内存四区图弄清楚的。
	fun(&node);
	return 0;
}
*/
//测试点6主要就是为了验证我之前说的一些结论。因为每一次在编程的时候不可能就每一次还
//去画一个内存四区图。所以,就给出了如下结论,这里总结一下:
//1.你想要通过函数改变指针的值,就要使用指针的指针
//2.改变一个指针的值,但是这个指针是另外一个指针的附加值,那么可以仅仅使用一个指针
//就可以达到改变的效果了。



评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值