- 论坛徽章:
- 2
|
回复 159# pandaiam
这代码里的(void*)转换和追加0不需要这么写, 所以也不需要去弄明白"为什么要这样做"。
下面是"为什么不需要这么做"。
void*本来就是为了仅仅表现一个地址而不表现类型而设计出来的。
在C标准化之前, 这个角色是char*担当。
那个时候的代码是这样:
- char* malloc(unsigned s);
- /* 返回值我都忘记是啥了 */free(char* p);
- char* memset(char* dst, int val, unsigned s);
复制代码
- T* a = (T*)malloc( n * sizeof(T) );
- memset( (char*)a, 0, n * sizeof(T) );
- free( (char*) a );
复制代码 之后引入void*:
任意类型指针都可以隐式转换到void*。(C++同样)
void*也可以隐式转换到任意指针。 (C++有区别, 必须显式)
一个类型为T*的对象转换为void*对象, 然后再转换回T*, 保证值不变。
这样, 代码就变成了这样:
- void* malloc(size_t s); // 还引入了size_t
- void free(void* p);
- void* memset(void* dst, int val, size_t s);
复制代码 上面的3处类型转换都不需要了:
- /* 如果需要兼容C++, 下一行注释部分需要 */
- T* a =/* (T*) */malloc( n*sizeof(T) );
- memset(a, 0, sizeof(T) );
- free(a);
复制代码 C89标准里就有void*了。 21年了。
lz那种写法, 完全"没错"; 只是多余, 完全不了解void*被引入的意图。
学任何技术, 严谨很重要的态度。
以lz那种治学态度, 在137楼一边喊着避免段错误, 一边写出段错误的代码, 绝对不是偶然。
对了, 从技术上讲, 真存在一些地方显示的void*转化是必须加的。
—— 比如在没有函数原型或者变长参数列表的时候
- int i = ...;
- printf("%p\n", (void*)&i );
- printf("null=%p\n", (void*)0 );
复制代码 只是那种指针格式怪异的平台越来越少, 所以很多时候不加也不会出错。 |
|