代码架构一(借助局部变量和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
}
上一篇下一篇

猜你喜欢

热点阅读