通俗的来说,值传递只是把变量的值当做参数传递进子函数中,无论函数体中如何改变参数值,主函数的变量值都不会改变。
而地址传递,是把变量的地址传入子函数中,子函数中对于参数的改变,是通过传入的地址参数去内存中修改该变量存储的值,所以主函数中的变量值也会同步改变。
下面来演示一下c语言中如何改变结构体中的变量值:
#include <stdio.h>
#include <stdlib.h>
typedef struct Table{
int * head;
int length;
int size;
}table;
//初始化
void initTable(table *t,int size){
(*t).head=(int*)malloc(size*sizeof(int));
if (!(*t).head)
{
printf("初始化分配失败");
return;
}
(*t).length=0;
(*t).size=size;
}
//地址传递
void addByAddress(table *t,int newElement,int index){
int i =0;
if(index<1|| index>(*t).length+1){
printf("插入位置 %d 不对!,现有数据总数为 %d \n",index,(*t).length);
return;
}
if((*t).length>=(*t).size){
(*t).head = (int*)realloc((*t).head,((*t).size+1)*sizeof(int));
if (!(*t).head) {
printf("存储分配失败");
return;
}
(*t).size += 1;
}
//如果插入位置小于等于length,则需要把元素后移
for(i =(*t).length-1;i>=index-1;i--){
(*t).head[i+1] = (*t).head[i];
}
(*t).head[index-1] = newElement;
//不能使用(*t).head[i] = newElement;
(*t).length++;
}
//值传递
void addByValue(table t,int newElement,int index)
{
if (index >t.length+1||index <1) {
printf("插入位置 %d 不对!,现有数据总数为 %d \n",index,t.length);
return;
}
if (t.length>=t.size) {
t.head=(int *)realloc(t.head, (t.size+1)*sizeof(int));
if (!t.head) {
printf("存储分配失败");
return;
}
t.size += 1;
}
for (int i=t.length-1; i>=index-1; i--) {
t.head[i+1]=t.head[i];
}
t.head[index-1]= newElement;
t.length++;
}
//打印结构体数组中的元素
void display(table t){
if(t.length == 0 )
printf("数组为空!");
for (int i=0;i<t.length;i++) {
printf("%d ",t.head[i]);
}
printf("\n");
}
//主函数
int main(){
table t,t1;
initTable(&t,10);
initTable(&t1,10);
int i=0;
//增加元素
printf("地址传递:\n");
//传递地址
for(i =0;i<10;i++){
addByAddress(&t,i+1,i+1);
}
display(t);
//传递值
printf("\n值传递:\n");
for(i =0;i<10;i++){
addByValue(t1,i+1,i+1);
}
display(t1);
return 0;
}
测试结果:
该结果表明,值传递中,子函数中无法改变主函数中变量的值,结果中,因为第一个位置没有数据,所以从下标2开始插入数据,就显示插入位置不对,最后打印结果也显示数组为空,即表示通过值传递无法向结构体中的数组增加数据。所以需要使用地址传递,将结构体的地址传递进去,就可以改变其数组的值了。