指针在函数形参的传递总结

        指针这东西真是个磨人的小妖精,有的时候觉得懂了,过了断时间写代码的时候又懵懵的。今天就好好总结下。

        我个人对指针的理解在写二叉树,二叉排序树的过程中升华了。相信小伙伴们也都不陌生,这里结合代码说说看。

        首先是一些易混,易模糊的概念。NULL是对指针的值的描述。指针的值就是指针变量存放的东西。我们说指针所指的对象,其实就是这个对象的地址作为指针的值。

        nullptr在C++11中出现,顾名思义其实就是描述空指针,使用起来差别不大。个人觉得没有必要深挖。

下面是二叉排序树的代码。现有创建,插入,中序遍历输出。

typedef struct sortTree {
	sortTree* lchild;
	sortTree* rchild;
	int val;//节点值
}sortTree,*tree;

void InsertBST(tree &t, int val) {
	if (t == nullptr)
	{
		t = new sortTree;
		t->val = val;
		t->lchild = nullptr;
		t->rchild = nullptr;
	}
	
    if (val > t->val) {
			InsertBST(t->rchild, val);
		}
	if (val < t->val) {
			InsertBST(t->lchild, val);
		}
	
}

void CreatBST(tree &t,int a[],int n) {
	
	//t = nullptr;
	int i = 0;
	while (i < n) {
	//	cout << a[i];
		InsertBST(t, a[i]);
		i++;
	}
}
void Traverse(tree t) {
	//cout << "v f da";
	//中序遍历检验
	if (t == NULL) {
		//cout << "gsdfg";
		return;
	}
	else {
		Traverse(t->lchild);
		cout << t->val << " ";
		Traverse(t->rchild);
	}
}
int main() {
	cout << "请输入二叉排序数的节点数" << endl;
	int x;
	tree test=NULL;
	cin >> x;
	int* s = new int[x];
	cout << "下面依次输入节点的值" << endl;
	for (int i = 0; i < x; i++) {
		cin >> s[i];	
	}
	CreatBST(test,s,x);
	Traverse(test);
}

        在main方法里,我们定义了结构体变量的指针test,且未初始化,如果在CreatBST函数中不用(&)取引用符,编译器运行时会提示未初始化。然而你若给它初始化 null 后,在执行其实什么也不会有,因为编译器会选择 值传递 的方式,也是在函数中复制一个 null指针的变量操作,由于这个操作在栈内存中,所以出来后跟test毛关系都没有。然后 在CreatBST函数中使用(&)取引用符,此时就是引用传递了,传的就是test这个指针变量的地址,注意不是它所存放的地址,注意! 这样函数的执行就是对这个test指针进行操作了。
         后面的中序遍历就不一样。虽然没有使用(&)取引用符,它传递的就是这个指针变量存放的地址了,上面说过指针变量的值就是它存放的东西的地址,在函数中是也复制了一个指针,这个指针变量的值就是test中的值。与由于中序遍历并不需要做改变,只是打印出过程。其实可加也可不加&。但是要改变东西也是可以,因为地址一样了就可以用 * 对它指向的东西操作了。比如中序遍历 输出代码可以

        Traverse(t->lchild);
		cout << (*t).val << " ";
		Traverse(t->rchild);

        所以,有&为引用传递,可以理解函数获取了这个变量的地址。
        而没有则为值传递,但这个指针或是其他的变量是一定要赋初值的。没有赋初值无法运行。

        在写的过程中我去试错了多种情况,为了探寻真理。如果一个指针没有初始化,但函数中有& ,是可以运行 ,不过 未初始化的指针会指向一个不确定地址 ,运行中肯定出错,而且这是相当危险的。而不是默认它的值为null,就像是int一个变量没有给它赋值而不会默认它为0。所以它仍是地址传递。

       下面说个指针传递。前面说了值传递和引用传递。这里引一个别人的代码和博客地址。
C++函数传递三种方式

void fun(int *x){

*x += 5; //修改的是指针x指向的内存单元值

}

void main(void){

int y = 0;

fun(&y);

cout<<<<\"y = \"<<y<<endl; //y = 5;

}

        指针传递,注意在main方法的函数调用中用到了&y,而在函数中参数是以定义指针变量的形式,这里告诉编译器的意思是:给我把变量的地址赋给我函数中的指针变量,也就是函数复制了一个指针,这个指针的值是y的地址。但注意第一份代码提到的有一种情况也是复制一个指针,不过它本身就是指针变量,所以值传递复制值相等的指针。而第二份代码中 y 不是一个指针变量,所以用& 对函数复制的指针进行赋值。

        希望对你有所帮助,共勉努力

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值