结构体知识------值传递和址传递
相关知识
- 相关知识
- 区别
- 值传递
- 址传递
- 例子
- 作用
- 程序
- 运行结果
- 普通变量(char a):a是变量名,对应内存空间的大小是sizeof(char),对应地址假设是0x001,也就是地址0x001存放的是变量a的值,存放的数据类型是字符型。
- 指针变量(char *p): 指针变量的本质还是一个变量,只不过存放的数据类型是地址。p是变量名,对应的内存空间的大小是sizeof(char *),对应的地址假设是0x002,也就是地址0x002中存放的是变量p的值,存放的数据类型是指针:int a = 1; a在内存中的地址假设是0x001。
- 形参是函数定义的时候用的,实参是调用函数的时候用的。 函数的参数都是形参,只有在函数调用的时候系统才会为形参分配空间和地址,形参和实参不会是同一个内存地址。 例如:
void fun(int a); /* 这里的a就是形参 */
int main()
{
int b = 1;
fun(b); /* b就是实参 */
}
区别
例如: 设:int a = 2; a在内存中的地址假设是0x0001
值传递值传递:传递的变量的值,就是传递的是2这个值。
/* 值传递 */
void fun(int b)
{
b = 1;
}
int main()
{
int a = 2;
fun(a);
printf("a=%d\n", a);
return 0;
}
值传递:调用fun函数的时候,系统会先为b分配空间,然后将a的值赋值给b,也就是b的值就等于2了。但是b的地址与a的地址是不同的,只是对应地址中存放的值是相同的。假设a的地址是0x001,b的地址是0x002,然后空间大小都是sizeof(int),0x001(a)地址空间中存放的是2,0x002(b)空间中的存放的值也是2。当b=1的时候,只是将0x002地址对应的空间赋值为1,与0x001地址对应的空间是没有关系的。所以a仍然是2。
址传递址传递:传递的是变量的地址,就是传递的是0x0001这个地址。
/* 址传递 */
void fun(int *b)
{
*b = 1;
}
int main()
{
int a = 2;
fun(&a);
printf("a=%d\n", a);
return 0;
}
址传递:调用fun函数的时候,b还是形参,只不过变成一个指针变量。假设a地址仍然是0x001,b的地址仍然是0x002。a的地址对应的内存空间中存放的是整型的2,b的地址对应的内存空间中存放的是一个地址,即a的地址0x001。当*b = 1的时候,操作的实际上是0x001这个空间,这个空间对应的就是变量a,所以a的值会变为1。
例子 作用可以很清楚的看出来A.a和A->a的区别。
程序#include
typedef struct
{
int a;
int b;
}AQ;
AQ s1; //定义变量s1,类型为AQ
AQ *s2; //定义指针变量s2,类型为AQ
void fun1(AQ s11);
void fun2(AQ *s22);
int main()
{
AQ s3={1,2};
s1=s3;
s2=&s3;
printf("\n\t");
printf("结构体变量方式:\n");
fun1(s1);
printf("s1.a is %d\n",s1.a);
printf("s1.b is %d\n",s1.b);
printf("\n\t");
printf("结构体指针变量方式:\n");
fun2(&s1);
printf("s1.a is %d\n",s1.a);
printf("s1.b is %d\n",s1.b);
printf("\n\t");
return 0;
}
void fun1(AQ s11)
{
printf("s1.a is %d\n",s11.a);
printf("s1.b is %d\n",s11.b);
s11.a=5;
s11.b=6;
}
void fun2(AQ *s22)
{
printf("s1.a is %d\n",s22->a);
printf("s1.b is %d\n",s22->b);
s22->a=7;
s22->b=8;
}
运行结果
由此可知: 通过结构体指针的方式可以改变成员变量的值 (A->a)。 通过结构体变量的方式,不可以改变成员变量的值。(A.a)
关注公众号,了解更多。