目录

问题

正确代码

两者区别

开启调试

设置监视的变量

逐过程调试

在自定义函数中调试

跳出自定义函数

对正确的代码进行调试

进入自定义函数

跳出自定义函数 

为什么说编译器有问题


问题

今天遇到一个很有意思的问题分享一下。他写了一个交换数据的函数,但是传入参数是指针,但无法改变数据。代码如下

#define  _CRT_SECURE_NO_WARNINGS 1

#include<stdio.h>

void swap(int* a, int* b)
{
	int t;
	t = a;
	a = b;
	b = t;
}

int main()
{
	int x = 12, y = 63;
	swap(&x, &y);
	printf("x=%d y=%d\n", x, y);
	return 0;
}

正确代码

#define  _CRT_SECURE_NO_WARNINGS 1

#include<stdio.h>

void swap(int* a, int* b)
{
	int t;
	t = *a;
	*a = *b;
	*b = t;
}

int main()
{
	int x = 12, y = 63;
	swap(&x, &y);
	printf("x=%d y=%d\n", x, y);
	return 0;
}

两者区别

我们拿错误的代码进行调试,本人使用的是VS2013作为讲解,其他编译器都有调试功能和查看变量功能,建议学习一下。不过编译器快捷键应该都类似。

开启调试

(1)首先我们按F11进入调试。

(2)窗口->监视->监视1, 打开监视窗口。(注意,这个必须在调试模式下才有)

函数传址,但无法改变xy数据问题_数据

设置监视的变量

 分别在名称下面写入变量名称。增加名称的方法是双击空白框。

函数传址,但无法改变xy数据问题_编译器_02

逐过程调试

在自定义函数中调试

我们按F11可以进行逐过程调试。我们先按F11进入自定义函数中

函数传址,但无法改变xy数据问题_自定义函数_03

我们逐过程运行,发现a和b指针指向的地址发生了改变,但是需要注意一点。指针指向地址的内容没有变!!! 

这就是问题的关键! 因为我们发现,在逐过程调试过程,实参x和y的数据根本就没有变化

函数传址,但无法改变xy数据问题_c语言_04

跳出自定义函数

跳出自定义函数,形参释放,实参没有变化!

函数传址,但无法改变xy数据问题_数据_05

对正确的代码进行调试

进入自定义函数

现在我们依旧按照上面步骤进入自定义函数。

函数传址,但无法改变xy数据问题_数据_06

然后逐过程运行,到自定义函数快结束。我们发现x和y的值没有发生变化。(这个我猜是编译器调试有点小问题,影响不大。为什么我怀疑编译器调试有问题,后面讲) 

函数传址,但无法改变xy数据问题_数据_07

跳出自定义函数 

现在我们发现x和y的值发生了改变。为什么呢?因为在自定义函数中,我们是对指针所指向的区域进行了数据上的改变。这个改变是实实在在的,不会因为形参的释放数据而发生改变。

但是如果只是指针交换,那么随着形参的释放,这个指针交换并没有反应到实参当中。

函数传址,但无法改变xy数据问题_自定义函数_08

为什么说编译器有问题

因为我们进行指针内部数据交换,x也要随着在自定义函数中的逐过程发生变化。但是这里没有,我怀疑是因为这个在自定义函数调试过程,编译器不会读取实参的数据。所以才没有进行实时变化。

函数传址,但无法改变xy数据问题_数据_09