C 空指针的用途是什么?

C 空指针的用途是什么?,c,pointers,casting,void-pointers,C,Pointers,Casting,Void Pointers,既然可以将任何指针类型转换为任何指针类型,那么为什么必须使用空指针,即: char b = 5; int*a = (int*)&b;//both upcasting 或 ? 另外,为什么在使用malloc/calloc/realloc时不需要强制转换?void指针对于创建通用API非常有用。您可能会想到qsort函数,该函数可用于对任何类型的数组进行排序void指针 void qsort( void *base, size_t number, size_t widt

既然可以将任何指针类型转换为任何指针类型,那么为什么必须使用空指针,即:

char b = 5; 
int*a = (int*)&b;//both upcasting

?


另外,为什么在使用malloc/calloc/realloc时不需要强制转换?

void
指针对于创建通用API非常有用。您可能会想到
qsort
函数,该函数可用于对任何类型的数组进行排序<如果API不知道指针的具体类型,则可以使用code>void指针

void qsort(
   void *base,
   size_t number,
   size_t width,
   int (__cdecl *compare )(const void *, const void *)
);
关于分配函数,也是一样的。C运行时不知道有效对象的类型。但这不是问题,因为用户可以使用通用指针
void


所以
void
指针被认为是泛型指针,对于多态性非常有用,这就是为什么C语言将强制转换为
void
作为可选的原因。

void
指针对于创建泛型API非常有用。您可能会想到
qsort
函数,该函数可用于对任何类型的数组进行排序<如果API不知道指针的具体类型,则可以使用code>void指针

void qsort(
   void *base,
   size_t number,
   size_t width,
   int (__cdecl *compare )(const void *, const void *)
);
关于分配函数,也是一样的。C运行时不知道有效对象的类型。但这不是问题,因为用户可以使用通用指针
void

所以
void
指针被认为是泛型指针,对于多态性非常有用,这就是为什么C语言将强制转换为
void
视为可选的原因。

“只要可以强制转换任何指针类型,为什么必须使用void指针?”

alloc函数必须使用公共分母,比如char。但是,如果我们必须投入到我们真正需要的东西上,那将是令人困惑的。“void”只是指“一堆字节”。

“既然可以强制转换任何指针类型,为什么void指针是必需的?”

alloc函数必须使用公共分母,比如char。但是,如果我们必须投入到我们真正需要的东西上,那将是令人困惑的。“void”只是指“一堆字节”

可以将任何指针类型强制转换为任何指针类型

不完全是
void*
定义为将任何对象指针1转换为
void*
,然后使用等效值返回。它不需要任何石膏

在不太常见的体系结构中,一些其他指针的大小和范围可能小于
void*
。在其他指针类型之间强制转换可能会丢失必要的信息

void*
提供通用对象指针类型

void *p = any_object_pointer; // No casts required
any_object_pointer = p;       // No casts required
char*
可以替代
void*
,但与其他对象指针的转换需要强制转换


OP的
字符b=5;int*a=(int*)&bint*
的对齐需求可能超过
char*
,因此code>存在未定义行为的风险


1函数指针的宽度可能大于
void*
void*
和其他指针都是对象指针。C缺少真正通用的指针类型

void *p = any_object_pointer; // No casts required
any_object_pointer = p;       // No casts required
可以将任何指针类型强制转换为任何指针类型

不完全是
void*
定义为将任何对象指针1转换为
void*
,然后使用等效值返回。它不需要任何石膏

在不太常见的体系结构中,一些其他指针的大小和范围可能小于
void*
。在其他指针类型之间强制转换可能会丢失必要的信息

void*
提供通用对象指针类型

void *p = any_object_pointer; // No casts required
any_object_pointer = p;       // No casts required
char*
可以替代
void*
,但与其他对象指针的转换需要强制转换


OP的
字符b=5;int*a=(int*)&bint*
的对齐需求可能超过
char*
,因此code>存在未定义行为的风险



1函数指针的宽度可能大于
void*
void*
和其他指针都是对象指针。C缺乏真正通用的指针类型。

“@pauk”中详细介绍的“为什么在使用malloc/calloc/realloc时不需要强制转换”可以将任何指针类型强制转换为任何指针类型”-->好奇,谁或什么文本建议了这一点?@pauk我花时间解决了您的问题。我的想法是什么?@pauk中详细介绍的“为什么在使用malloc/calloc/realloc时不需要强制转换”可以将任何指针类型强制转换为任何指针类型”-->好奇,谁或什么文本建议了这一点?@pauk我花时间解决了您的问题。我的想法是什么?需要注意的是,更改指针类型不会更改指向的对象的类型,因此,在任意类型的指针之间进行强制转换通常是不安全的。事实上,我看到C需要一个不应显式强制转换的通用类型指针。尽管如此,我不明白为什么强制转换到特定类型的指针是有风险的,只要指针类型仅在指针算术方面起作用,因为指针指向内存位置,而不管其类型如何。此外,也许我应该打开另一个主题,但我看不到强制转换本身的目的,只要指针类型只在涉及指针算术时起作用,那么,例如,将char*传递给int*不能破坏内存内容。@pauk“只要指针类型只在指针算术方面起作用”,就不是真的。1) “例如,将char*传递给int*”会产生问题。示例:当
int*
只能处理偶数地址,而
char*
可以处理夏娃/奇数地址时。2) 类型允许优化-研究抗锯齿,因为编译器“知道”通过
double*
操作对象不会通过
int*
更改某些内容。同时研究
restrict
3)铸造失败类型检查。这种弱类型检查属于C语言的前辈——我们没有听说这是有充分理由的——太容易出错。我理解得更好。非常重要的一点是,更改指针类型不会更改
void *p = any_object_pointer; // No casts required
any_object_pointer = p;       // No casts required