1

我很难理解C 中 bsearch 函数的这个实现中的第一行代码。我理解搜索算法本身,我已经玩过这个函数来很好地掌握它,但我仍然不明白什么

const char *base = (const char *) base0;

确实可以,为什么允许它,为什么它必须是 char 而不能是其他类型。当我使用相同的函数但使用类型转换来(const int*) base0;代替然后使用C Tutor来了解发生了什么时,我注意到变量 p 变成了指向无效内存的指针,但我不知道它为什么会发生以及为什么这个函数适用于两个字符串和整数。

4

1 回答 1

1

在函数中,您需要找到传递数组中的每个元素。但是数组的类型是未知的。你只知道数组每个元素的大小以及通过参数base0传递的数组的起始地址。类型const void *..

要访问数组的元素,您需要使用指针算法。但是类型 void 是不完整类型。它的大小是未知的/因此您不能在具有指针运算的表达式中使用类型 (const) void *` 的指针。

因此这个声明

const char *base = (const char *) base0;

介绍了 const char * 类型的指针基数,您可以使用指针算法访问数组的元素,如本语句所示

p = base + (lim >> 1) * size;

或者 examplebase + 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 )来访问传递数组的元素。

于 2021-06-15T21:14:44.117 回答