代码架构一(借助局部变量和void *)
2021-12-31 本文已影响0人
技术是神奇的
利用局部变量或全局变量天生会自动分配内存空间的特性
错误示范1:
struct testA {
int a;
};
void main() {
struct testA *ptr;
ptr->a = 10;
}
以上代码片段运行会报错:Segmentation fault 即段错误,原因是还没有给testA结构体分配空间。
正确示范1:
struct testA {
int a;
};
void main() {
struct testA tst; // 这行是关键,局部变量会自动分配内存空间
struct testA *ptr = &tst;
ptr->a = 10;
}
以上代码运行正确!充分利用了局部变量的特性,当然改成全局变量也是一样的。
利用void *可以表示任何地址的特点来传递指针地址
注:任何类型的指针地址所占的空间都是固定的。
比如,在64位的电脑,指针地址占用的字节为8
char *a;
int *b;
printf("%d %d\n", sizeof (char *), sizeof(a)); //输出 8 8
printf("%d %d\n", sizeof (int *), sizeof(b)); //输出 8 8
下面修改一下testA结构体,增加testC结构体, 同时增加testB结构体作为中间层用于传递地址。
struct testB {
void * struct_testC_handle;
};
struct testC {
int c;
};
struct testA {
int a;
struct testC *struct_testC_handle;
};
void main() {
struct testA *p_a;
struct testB tstB;
struct testC tstC;
p_a->struct_testC_handle = &tstC; //开辟一个空间存放testC结构体,这个空间的名字叫tstC,结构体testA中的指针struct_testC_handle,指向tstC空间的首地址
tstB.struct_testC_handle = p_a->struct_testC_handle;//这步是关键,为后面的强制类型转换奠定了条件。testB结构体里面的指针struct_testC_handle是void *类型,可以指向任意类型的结构体(当然确定指向哪种类型后,后面解析也要用这种类型);同时也方便传递参数(传递参数时只需要考虑变量,不需要考虑类型)
p_a->struct_testC_handle->c = 666;//通过结构体testA给testC结构体变量赋值
struct testC *p_c = (struct testC *)tstB.struct_testC_handle;//这里是强制类型转换,可以通过testB结构体这个中间变量实现了地址传递
printf("%d\n", p_c->c); // 输出 666
}