1、值传参,对形参的任何操作都不会对实参产生影响
1.1:值传参方法
//值传参
void NoChangeValue(int v) {
printf("值传参修改前的值 = %d\n", v);
v = 10;
printf("值传参修改后的值 = %d\n", v);
}
1.2:主方法
void main() {
int n = 1;
printf("\n----------------------NoChangeValue------------------------------------\n\n");
printf("调用前的值是 = %d\n", n);
printf("\n------------start---------\n\n");
NoChangeValue(n);
printf("\n------------end-----------\n\n");
printf("调用后的值 = %d,还是原值\n", n);
}
1.3:运行结果
1.4:解释
当主程序调用一个方法时,会产生一个栈帧。在栈帧中,包含方法的形参、方法的局部变量。执行方法时,会将实参的值赋值给栈帧中的形参。因此:对形参的操作不会影响到实参。
2、值的引用传参,对形参的任何操作都会对实参产生影响
2.1:引用传参方法
void ChangeValue(int &v) {
printf("值传参修改前的值 = %d\n", v);
v = 10;
printf("值传参修改后的值 = %d\n", v);
}
2.2:主方法
void main(){
int n = 2;
int* p = &n;
printf("\n----------------------ChangeValue------------------------------------\n\n");
printf("调用前的值是 = %d\n", n);
printf("\n------------start---------\n\n");
ChangeValue(n);
printf("\n------------end-----------\n\n");
printf("调用后的值是 = %d,不再是原值\n", n);
}
2.3:运行结果
2.4:解释
引用相当于是外部变量的别名,实际操作的就是该变量,即在函数内对该变量进行修改的话,在外部该变量也会相应被修改。
3、指针传参第一种,直接改变指向的值
3.1:指针传参方法
void ChangePtrValue(int* p){
printf("分配内存前p的地址 = %d \t 分配内存前p指向的地址 = %d \t 分配内存前p指向地址上的数值 = %d\t\n", &p,p,*p);
*p = 3;//直接改变指向的值
printf("分配内存后p的地址 = %d \t 分配内存后p指向的地址 = %d \t 分配内存后p指向地址上的数值 = %d\t\n", &p,p,*p);
}
3.2:主方法
void main(){
int n = 2;
int* p = &n;
printf("----------------------ChangePtrValue------------------------------------\n\n");
printf("方法调用前p的地址 = %d \t 方法调用前p指向的地址 = %d \t 方法调用前p指向地址上的数值 = %d\t\n", &p,p,*p);
printf("\n------------start---------\n\n");
ChangePtrValue(p);
printf("\n------------end-----------\n\n");
printf("方法调用后p的地址 = %d \t 方法调用后p指向的地址 = %d \t 方法调用后p指向地址上的数值 = %d\t\n", &p,p,*p);
}
3.3:运行结果
3.4:解释
第一种是直接把值存放到指针存放的地址空间中,即:*p=10
4、指针传参第二种,通过改变指针指向的地址空间,来间接的改变指针指向的值(其实并不可以改变)
4.1:指针传参方法
//不可改变指针所指向的地址
void NoChangePtrAddress(int* p) {
printf("分配内存前p的地址 = %d \t 分配内存前p指向的地址 = %d \t 分配内存前p指向地址上的数值 = %d\t\n", &p,p,*p);
int n = 3;
p = &n;
printf("分配内存后p的地址 = %d \t 分配内存后p指向的地址 = %d \t 分配内存后p指向地址上的数值 = %d\t\n", &p,p,*p);
}
4.2:主方法
void main(){
int n = 2;
int* p = &n;
printf("----------------------NoChangePtrAddress------------------------------------\n\n");
printf("方法调用前p的地址 = %d \t 方法调用前p指向的地址 = %d \t 方法调用前p指向地址上的数值 = %d\t\n", &p,p,*p);
printf("\n------------start---------\n\n");
NoChangePtrAddress(p);
printf("\n------------end-----------\n\n");
printf("方法调用后p的地址 = %d \t 方法调用后p指向的地址 = %d \t 方法调用后p指向地址上的数值 = %d\t\n", &p,p,*p);
}
4.3:运行结果
4.4:解释
第二种是在方法中通过将变量的地址存放到形参指针中,使形参指针指向另一个地址空间,间接的修改形参指针指向的值。在方法调用过程生成的栈帧中,该指针是局部的,是因为它只是实参指针的一个拷贝,对局部变量 的修改并不会改变实际指针。因此:不会像指针传参第一种一样。
5、指针引用传参第一类,仅会改变指针指向的地址(即改变指针的内容),而使得指针指向的值出现非法现象
5.1:指针传参方法
//可改变指针所指向的地址
void ChangePtrAddress(int* &p) {
printf("分配内存前p的地址 = %d \t 分配内存前p指向的地址 = %d \t 分配内存前p指向地址上的数值 = %d\t\n", &p,p,*p);
int n = 3;
p = &n;//改变指针指向的地址空间
printf("分配内存后p的地址 = %d \t 分配内存后p指向的地址 = %d \t 分配内存后p指向地址上的数值 = %d\t\n", &p,p,*p);
}
5.2:主方法
void main(){
int n = 2;
int* p = &n;
printf("----------------------NoChangePtrAddress------------------------------------\n\n");
printf("方法调用前p的地址 = %d \t 方法调用前p指向的地址 = %d \t 方法调用前p指向地址上的数值 = %d\t\n", &p,p,*p);
printf("\n------------start---------\n\n");
NoChangePtrAddress(p);
printf("\n------------end-----------\n\n");
printf("方法调用后p的地址 = %d \t 方法调用后p指向的地址 = %d \t 方法调用后p指向地址上的数值 = %d\t\n", &p,p,*p);
}
5.3:运行结果
5.4:解释
之所有会出现非法,是因为int n = 3;p = &n;n是一个局部变量,当方法调用结束时,会对该空间进行释放,因此出现不符合实际的情况。而指针指向的地址发生改变(虽然该地址不存在),这是因为在引用传参中,对形参的操作就是对实参的操作。
6、指针引用传参第二类,如同指针传参第一种,直接改变指向的值(即使用*p=10;)。再在此不在多讲。
7、结论
若要改变值实参,通过值引用传参、或通过指向其地址的指针来进行指针传参。
若要改变指针中的内容(即指针指向的地址),使用指针引用传参第一类。
若要改变指针指向地址空间的内容,使用指针引用传参第二类或指针传参第一类。