需要帮助理解 C 中的类型转换 const void 指针
Need help understanding typecasting const void pointer in C
我无法理解 this 在 C 中实现的 bsearch 函数的第一行代码。我理解搜索算法本身,并且我已经尝试过这个函数来很好地掌握它但是我还是不明白什么
const char *base = (const char *) base0;
确实可以,为什么允许,为什么必须是 char 而不能是其他类型。当我使用相同的函数但将类型转换为 (const int*) base0;
然后使用 C Tutor 来了解发生了什么时,我注意到变量 p 变成了指向无效内存的指针,但我不知道为什么会这样以及为什么这个函数对字符串和整数都有效。
在函数中,您需要找到传递的数组中的每个元素。但是数组的类型是未知的。你只知道数组每个元素的大小和通过参数base0传递的数组起始地址。 const void *
..
类型
要访问数组的元素,您需要使用指针算法。但是类型 void 是不完整的类型。它的大小未知/因此您不能在具有指针算法的表达式中使用 (const) void *` 类型的指针。
因此声明
const char *base = (const char *) base0;
引入类型为 const char * 的指针基数,您可以使用指针算术访问数组元素,如本语句中所示
p = base + (lim >> 1) * size;
或者示例base + size
将指向数组的第二个元素。
这是一个演示程序。
#include <stdio.h>
void f( const void *base, size_t nmemb, size_t size )
{
for ( size_t i = 0; i < nmemb; i++ )
{
const char *p = ( const char * )base;
printf( "The address of the %zu-th element is %p\n",
i, ( const void *)( p + i * size ) );
}
}
int main(void)
{
int a[] = { 1, 2, 3 };
const size_t N = sizeof( a ) / sizeof( *a );
for ( size_t i = 0; i < N; i++ )
{
printf( "The address of the %zu-th element is %p\n",
i, ( const void *)( a + i ) );
}
putchar( '\n' );
f( a, N, sizeof( int ) );
return 0;
}
程序输出可能看起来像
The address of the 0-th element is 0x7ffc45c6d4dc
The address of the 1-th element is 0x7ffc45c6d4e0
The address of the 2-th element is 0x7ffc45c6d4e4
The address of the 0-th element is 0x7ffc45c6d4dc
The address of the 1-th element is 0x7ffc45c6d4e0
The address of the 2-th element is 0x7ffc45c6d4e4
在 main 中,您可以使用表达式 ( a + i )
来使用指针算法,因为在这个表达式中,数组指示符被隐式转换为类型 int *
并且类型 int
是一个完整类型(已知其大小)。
但是在函数 f 中你不能使用表达式 ( base + i )
因为指针的类型是 const void *
而类型 void 不是一个完整的类型(它的大小是未知的)。
因此将指针转换为类型 const char *
我们可以对这个指针使用指针算法,但在这种情况下我们需要使用表达式 ( p + i * size )
来访问传递的数组的元素。
我无法理解 this 在 C 中实现的 bsearch 函数的第一行代码。我理解搜索算法本身,并且我已经尝试过这个函数来很好地掌握它但是我还是不明白什么
const char *base = (const char *) base0;
确实可以,为什么允许,为什么必须是 char 而不能是其他类型。当我使用相同的函数但将类型转换为 (const int*) base0;
然后使用 C Tutor 来了解发生了什么时,我注意到变量 p 变成了指向无效内存的指针,但我不知道为什么会这样以及为什么这个函数对字符串和整数都有效。
在函数中,您需要找到传递的数组中的每个元素。但是数组的类型是未知的。你只知道数组每个元素的大小和通过参数base0传递的数组起始地址。 const void *
..
要访问数组的元素,您需要使用指针算法。但是类型 void 是不完整的类型。它的大小未知/因此您不能在具有指针算法的表达式中使用 (const) void *` 类型的指针。
因此声明
const char *base = (const char *) base0;
引入类型为 const char * 的指针基数,您可以使用指针算术访问数组元素,如本语句中所示
p = base + (lim >> 1) * size;
或者示例base + size
将指向数组的第二个元素。
这是一个演示程序。
#include <stdio.h>
void f( const void *base, size_t nmemb, size_t size )
{
for ( size_t i = 0; i < nmemb; i++ )
{
const char *p = ( const char * )base;
printf( "The address of the %zu-th element is %p\n",
i, ( const void *)( p + i * size ) );
}
}
int main(void)
{
int a[] = { 1, 2, 3 };
const size_t N = sizeof( a ) / sizeof( *a );
for ( size_t i = 0; i < N; i++ )
{
printf( "The address of the %zu-th element is %p\n",
i, ( const void *)( a + i ) );
}
putchar( '\n' );
f( a, N, sizeof( int ) );
return 0;
}
程序输出可能看起来像
The address of the 0-th element is 0x7ffc45c6d4dc
The address of the 1-th element is 0x7ffc45c6d4e0
The address of the 2-th element is 0x7ffc45c6d4e4
The address of the 0-th element is 0x7ffc45c6d4dc
The address of the 1-th element is 0x7ffc45c6d4e0
The address of the 2-th element is 0x7ffc45c6d4e4
在 main 中,您可以使用表达式 ( a + i )
来使用指针算法,因为在这个表达式中,数组指示符被隐式转换为类型 int *
并且类型 int
是一个完整类型(已知其大小)。
但是在函数 f 中你不能使用表达式 ( base + i )
因为指针的类型是 const void *
而类型 void 不是一个完整的类型(它的大小是未知的)。
因此将指针转换为类型 const char *
我们可以对这个指针使用指针算法,但在这种情况下我们需要使用表达式 ( p + i * size )
来访问传递的数组的元素。