为什么指针被誉为 C 语言灵魂?( 五 )


为什么指针被誉为 C 语言灵魂?文章插图
神奇的 void 指针想必大家一定看到过 void 的这些用法:
1 voidfunc;
2 intfunc1(void);
在这些情况下 , void 表达的意思就是没有返回值或者参数为空 。
但是对于 void 型指针却表示通用指针 , 可以用来存放任何数据类型的引用 。
下面的例子就 是一个 void 指针:
1void *ptr;
void 指针最大的用处就是在 C 语言中实现泛型编程 , 因为任何指针都可以被赋给 void 指针 , void 指针也可以被转换回原来的指针类型 ,并且这个过程指针实际所指向的地址并不会发生变化 。
比如:
1int num;
2int *pi =
3printf("address of pi: %p\n", pi);
4void* pv = pi;
5pi = (int*) pv;
6printf("address of pi: %p\n", pi);
这两次输出的值都会是一样:
为什么指针被誉为 C 语言灵魂?文章插图
平常可能很少会这样去转换 , 但是当你用 C 写大型软件或者写一些通用库的时候 , 一定离不开 void 指针 , 这是 C 泛型的基石 , 比如 std 库里的 sort 函数申明是这样的:
1void qsort(void *base,int nelem,int width,int (*fcmp)(const void *,const void *));
所有关于具体元素类型的地方全部用 void 代替 。
void 还可以用来实现 C 语言中的多态 , 这是一个挺好玩的东西 。
不过也有需要注意的:

  • 不能对 void 指针解引用
比如:
1int num;
2void *pv = (void*)
3*pv = 4; // 错误
为什么?
因为解引用的本质就是编译器根据指针所指的类型 , 然后从指针所指向的内存连续取 N 个字节 , 然后将这 N 个字节按照指针的类型去解释 。
比如 int *型指针 , 那么这里 N 就是 4 , 然后按照 int 的编码方式去解释数字 。
但是 void , 编译器是不知道它到底指向的是 int、double、或者是一个结构体 , 所以编译器没法对 void 型指针解引用 。
为什么指针被誉为 C 语言灵魂?文章插图
花式秀技很多同学认为 C 就只能面向过程编程 , 实际上利用指针和结构体 , 我们一样可以在 C 中模拟出对象、继承、多态等东西 。
也可以利用 void 指针实现泛型编程 , 也就是 Java、C++ 中的模板 。
大家如果对 C 实现面向对象、模板、继承这些感兴趣的话 , 可以积极一点 , 点赞 , 留言~ 呼声高的话 , 我就再写一篇 。
实际上也是很有趣的东西 , 当你知道了如何用 C 去实现这些东西 , 那你对 C++ 中的对象、Java 中的对象也会理解得更加透彻 。
比如为啥有 this 指针 , 或者 Python 中的 self 究竟是个啥?
关于指针想写的内容还有很多 , 这其实也只算是开了个头 , 限于篇幅 , 以后有机会补齐以下内容:
  • 二维数组和二维指针
  • 数组指针和指针数组
  • 指针运算
  • 函数指针
  • 动态内存分配: malloc 和 free
  • 堆、栈
  • 函数参数传递方式
  • 内存泄露
  • 数组退化成指针
  • const 修饰指针
  • ...
基本上涵盖了 C 语言最核心的知识 。
絮叨我其实挺想写一个系列 , 大概就是关于内存、指针、引用、函数调用、堆栈、面向对象实现机制等等这样的底层一点的东西 。
为什么指针被誉为 C 语言灵魂?文章插图
为什么指针被誉为 C 语言灵魂?文章插图
为什么指针被誉为 C 语言灵魂?文章插图
【为什么指针被誉为 C 语言灵魂?】点分享
为什么指针被誉为 C 语言灵魂?文章插图
为什么指针被誉为 C 语言灵魂?文章插图