函数的传递的参数是原参数的副本
使用C语言编程,不可能不用到函数,但是函数的参数传递,我们是否真的清楚了呢。本文主要介绍C语言中函数传递的参数。。
函数的参数通常分为两种,普通变量,指针变量。这些参数,将会被函数体调用,当让,也可以传入一些永远不被函数调用的参数,就像你声明了一些变量,却永远不用一样,在语法上是没有问题的。
那么,函数体内调用的传递过来的参数,与原来的参数有什么关系呢?
函数体内接收到的参数,是原参数的副本。
1. 普通变量在函数中的传递 首先我们来看普通变量,函数体内的参数为该普通变量的拷贝副本。下面是一个例子的源程序:
#include <stdio.h>
#include <stdlib.h>
int test(int t1, int t2);
int main(int argc, char *argv[])
{
int t1 = 10;
int t2 = 0;
printf("[main]t1: %d\tt1:%x\n", t1, &t1);
printf("[main]t2: %d\tt2:%x\n", t2, &t2);
test(t1, t2);
printf("[main]t1: %d\tt1:%x\n", t1, &t1);
printf("[main]t2: %d\tt2:%x\n", t2, &t2);
system("PAUSE");
return 0;
}
int test(int t1, int t2)
{
printf("in func....\n");
printf("[test]t1: %d\tt1:%x\n", t1, &t1);
printf("[test]t2: %d\tt2:%x\n", t2, &t2);
t2 = t1;
printf("[test]after t2 = t1\n");
printf("[test]t1: %d\tt1:%x\n", t1, &t1);
printf("[test]t2: %d\tt2:%x\n", t2, &t2);
printf("in func over....\n");
return 1;
}
执行结果为:
[main]t1: 10 t1:22ff7c
[main]t2: 0 t2:22ff78
in func....
[test]t1: 10 t1:22ff60
[test]t2: 0 t2:22ff64
[test]after t2 = t1
[test]t1: 10 t1:22ff60
[test]t2: 10 t2:22ff64
in func over....
[main]t1: 10 t1:22ff7c
[main]t2: 0 t2:22ff78
(打印的地址值可能与我获得的结果不同。)
可以看到,t1和t2,在被test函数调用前后,其值和地址都未变化。而在test函数中,t1和t2的地址与main函数中并不相同,其只是原来的t1和t2的拷贝副本。对副本作的一切操作,都不会影响到test函数外的原来的参数。
2. 指针变量在函数中的传递 指针作为变量在函数传递中,有些特殊,对于普通变量,函数传递的是对其的一份拷贝的副本,而对于指针,函数传递的是对其存放地址的一份拷贝,该拷贝存放的地址与原来的指针所存的地址一致。
我们来看看例子程序:
#include <stdio.h>
#include <stdlib.h>
int test(char *t1, char *t2);
int main(int argc, char *argv[])
{
char t1[] = "kdsfkasdfkdsf";
char *t2 = NULL;
printf("[main]t1: %s\tt1:%x\t&t1:%x\n", t1, t1, &t1);
printf("[main]t2: %s\tt2:%x\t\t&t2:%x\n", t2, t2, &t2);
test(t1, t2);
printf("[main]t1: %s\tt1:%x\t&t1:%x\n", t1, t1, &t1);
printf("[main]t2: %s\tt2:%x\t\t&t2:%x\n", t2, t2, &t2);
system("PAUSE");
return 0;
}
int test(char *t1, char *t2)
{
printf("in func....\n");
printf("[test]t1: %s\tt1:%x\t&t1:%x\n", t1, t1, &t1);
printf("[test]t2: %s\tt2:%x\t\t&t2:%x\n", t2, t2, &t2);
t2 = t1;
printf("[test]after t2 = t1\n");
printf("[test]t1: %s\tt1:%x\t&t1:%x\n", t1, t1, &t1);
printf("[test]t2: %s\tt2:%x\t&t2:%x\n", t2, t2, &t2);
printf("in func over....\n");
return 1;
}
输出结果为:
[main]t1: kdsfkasdfkdsf t1:22ff68 &t1:22ff68
[main]t2: (null) t2:0 &t2:22ff64
in func....
[test]t1: kdsfkasdfkdsf t1:22ff68 &t1:22ff40
[test]t2: (null) t2:0 &t2:22ff44
[test]after t2 = t1
[test]t1: kdsfkasdfkdsf t1:22ff68 &t1:22ff40
[test]t2: kdsfkasdfkdsf t2:22ff68 &t2:22ff44
in func over....
[main]t1: kdsfkasdfkdsf t1:22ff68 &t1:22ff68
[main]t2: (null) t2:0 &t2:22ff64
(打印的地址值可能与我获得的结果不同。)
可以看到,在main函数中,t1、t2所存放的地址,以及该地址对应的字符串的值,与test函数中传递的t1、t2完全一样,但t1、t2的地址却完全不同,
l 故指针在函数中传递的是其地址的一份拷贝,可以在函数体内,修改指针存放的地址对应的值,其修改在函数体外对原参数同样有效,因为原参数也指向该地址。
l 指针在函数体内可修改其所存放的地址,但其修改对函数体外原指针参数无效,因为其只是原指针参数的地址副本,原指针依然指向原来的地址。
3. 使用指针的指针在函数体内修改指针所指对象 如果一定要修改指针参数所指的地址,应该怎么作呢?这时,我们需要用到指针的指针了。请看例子程序:
#include <stdio.h>
#include <stdlib.h>
int test(char **t1, char **t2);
int main(int argc, char *argv[])
{
char *t1 = "tttt";
char *t2 = NULL;
printf("[main]t1: %s\tt1:%x\t&t1:%x\n", t1, t1, &t1);
printf("[main]t2: %s\tt2:%x\t&t2:%x\n", t2, t2, &t2);
test(&t1, &t2);
printf("[main]t1: %s\tt1:%x\t&t1:%x\n", t1, t1, &t1);
printf("[main]t2: %s\tt2:%x\t&t2:%x\n", t2, t2, &t2);
//printf("[main]t2: %s\n", t2);
system("PAUSE");
return 0;
}
int test(char **t1, char **t2)
{
printf("[test]in func....\n");
printf("[test]*t1: %s\tt1:%x\n", *t1, t1);
printf("[test]*t2: %s\tt2:%x\n", *t2, t2);
*t2 = *t1;
printf("[test]after *t2 = *t1\n");
printf("[test]*t1: %s\tt1:%x\n", *t1, t1);
printf("[test]*t2: %s\tt2:%x\n", *t2, t2);
printf("[test]in func over....\n");
return 1;
}