C语言中指针传递与值传递

C语言中指针传递与值传递


C语言中关于指针传递与值传递的问题经常遇到,但是每次都容易被自己忽视,没有引起重视。

首先看个比较简单的例子,我们需要实现一个a、b交换的函数

若使用值传递的方式则可能写成如下:

#include 
#include 

typedef unsigned char uint8_t;

void swop(uint8_t k, uint8_t n)
{
	uint8_t temp;

	temp = k;
	k = n;
	n = temp;
}


void main(void)
{
	uint8_t a = 3,b = 5;

	swop(a,b);

	printf("a = %d,b = %d\r\n",a,b);

	while(1);
}

测试会发现主函数调用swop函数后,a、b值根本不会发生改变:
C语言中指针传递与值传递_第1张图片
原因:k、n是系统在发生函数调用时生成的临时变量,虽然值和a、b相同,但却是两个不同地址空间的变量,这两个临时变量是运行swop函数临时生成的和主程序中的变量是完全独立的。在函数中我们看到临时变量k、n的值确实改变了,但swop函数调用完成后当返回主程序时,a、b的值并没有改变。

修改程序如下:

#include 
#include 

typedef unsigned char uint8_t;

void swop(uint8_t *k, uint8_t *n)
{
	uint8_t temp;

	temp = *k;
	*k = *n;
	*n = temp;
}


void main(void)
{
	uint8_t a = 3,b = 5;

	swop(&a,&b);

	printf("a = %d,b = %d\r\n",a,b);

	while(1);
}

运行结果如下
分析:修改程序后调用swop函数则传递的是a、b的地址值,swop函数内部交换操作则真正实现了对实际a、b地址指向的值交换。

接着我们看一个复杂点的例子,原理相同,却经常被忽视。功能是实现通过fun返回 test_buf的首地址功能。

经常回错误的写成如下:

#include 
#include 

typedef unsigned char uint8_t;

uint8_t test_buf[10] = {1,2,3,4,5,6,7,8,9,0};

/*通过fun返回 test_buf的首地址*/
void fun(uint8_t *p_back)
{
	p_back = test_buf;
}


void main(void)
{
	uint8_t *p = NULL;

	fun(p);

	printf("back data:%d\r\n",p[0]);

	while(1);
}

分析:实际运行根本不能得到想要的结果,p也不会指向test_buf。原因一样,*p_back 是发生fun调用时生成的临时指针变量,p_back和主函数中的p是不同地址空间的指针变量,虽然与p值相同,但不会改变p的值

正确的写法如下:

#include 
#include 

typedef unsigned char uint8_t;

uint8_t test_buf[10] = {1,2,3,4,5,6,7,8,9,0};

/*通过fun返回 test_buf的首地址*/
void fun(uint8_t **p_back)
{
	*p_back = test_buf;
}


void main(void)
{
	uint8_t *p = NULL;

	fun(&p);

	printf("back data:%d\r\n",p[0]);

	while(1);
}

分析如下:**p_back 表示指针的指针,也就是指针的地址,发生fun调用时是地址传递。变量都是有地址的,主函数中发生fun调用时传递的是&p,也就是指针p的地址,指针p的地址当然就是存放p指针变量的地址值,此时fun的功能就变成了将test_buf的首地址值赋值给p的地址,指针p变量地址的内容就变成了test_buf的首地址,则p指向了test_buf。

用更简单易理解的话说就是:你要传回去的是指针 所以需要一个指向指针的指针

你可能感兴趣的:(c)