C语言函数指针和字符串

函数指针是控制程序执行的一种非常灵活的方法。在本节中,我们会通过将比较函数传递给排序函数来说明这种能力。排序函数通过比较数组的元素来判断是否交换数组元素,比较决定了数组是按升序还是降序(或者其他排序策略)排列。通过传递一个函数来控制比较,排序函数会变得更灵活。传递不同的比较函数可以让同一个排序函数以不同的方式工作。

我们使用的比较函数根据数组的元素大小写决定排序顺序。下面的comparecompareIgnoreCase会根据大小写比较字符串。在用strcmp函数比较字符串之前,compareIgnoreCase函数会先把字符串转换成小写。5.2.1节中已经讨论过strcmp函数了。stringToLower函数返回动态分配内存的指针,这意味着一旦不需要就应该将其释放掉。

int compare(const char* s1, const char* s2) {
    return strcmp(s1,s2);
}

int compareIgnoreCase(const char* s1, const char* s2) {
    char* t1 = stringToLower(s1);
    char* t2 = stringToLower(s2);
    int result = strcmp(t1, t2);
    free(t1);
    free(t2);
    return result;
}

stringToLower函数如下所示,它将传递进来的字符串用小写的形式返回:

char* stringToLower(const char* string) {
    char *tmp = (char*) malloc(strlen(string) + 1);
    char *start = tmp;
    while (*string != 0) {
        *tmp++ = tolower(*string++);
    }
    *tmp = 0;
    return start;
}

使用如下的类型定义声明我们要使用的函数指针:

typedef int (fptrOperation)(const char*, const char*);

下面的sort函数的实现基于冒泡排序算法,我们将数组地址、数组长度以及一个控制排序的函数指针传递给它。在if语句中,调用传递进来的函数并传递数组的两个元素,它会判断这两个元素是否需要交换。

void sort(char *array[], int size, fptrOperation operation) {
    int swap = 1;
    while(swap) {
        swap = 0;
        for(int i=0; i<size-1; i++) {
            if(operation(array[i],array[i+1]) > 0){
                swap = 1;
                char *tmp = array[i];
                array[i] = array[i+1];
                array[i+1] = tmp;
            }
        }
    }
}

打印函数会显示数组的内容:

void displayNames(char* names[], int size) {
    for(int i=0; i<size; i++) {
        printf("%s ",names[i]);
    }
    printf("\n");
}

我们可以用两个比较函数中的任意一个作为参数调用sort函数。下面用compare函数进行区分大小写的排序:

char* names[] = {"Bob", "Ted", "Carol", "Alice", "alice"};
sort(names,5,compare);
displayNames(names,5);

输出如下:

Alice  Bob  Carol  Ted  alice

如果使用compareIgnoreCase函数,输出则是这样:

Alice  alice  Bob  Carol  Ted

这样sort函数就灵活得多了,我们可以设计并传递自己想要的任意简单或复杂的操作来控制排序,而不需要针对不同的排序需求写不同的排序函数。

Python教程

Java教程

Web教程

数据库教程

图形图像教程

大数据教程

开发工具教程

计算机教程