经典编程900例(c语言)(第九篇)

本文详细介绍了C/C++编程中的几个关键概念:字符串数组的冒泡排序、多级指针的使用、函数指针作为参数以及标准库函数的应用,如lfind与lsearch的比较,快速排序和选择排序的实现。通过实例演示,读者可以理解并掌握这些核心技术。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

例100:字符串数组的排序

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/**
 * 排序字符数组
 * @Author dust_fall
 * @param  array     要排序的数组
 * @param  size      数组的长度
 */
void bubble_sort(char *array[], int size)
{
    char *temp; 
    int i, j;

    for (i = 0; i < size; i++) 
        for (j = 0; j < size; j++)
            // strcmp字符串比较函数(对位比较字符的ASCII码值, 第一个比第二个大就>0, 小就小于0, 等于就等于0)需包含string.h
            if (strcmp(array[i], array[j]) < 0)
            {
                temp = array[i];
                array[i] = array[j];
                array[j] = temp;
            }
}

int main(int argc, char const *argv[])
{
    char *values[] = {"AAA", "CCC", "BBB", "EEE", "DDD"};
    int i;

    bubble_sort(values, 5);

    for (i = 0; i < 5; i++)
        printf("%s ", values[i]);	// AAA BBB CCC DDD EEE

    return 0;
}

例101:多级指针使用

#include <stdio.h>

int what_is_the_value(int ***ptr)
{
    return(***ptr);
}

int main(int argc, char const *argv[])
{
    int *level_1, **level_2, ***level_3, value = 1001;

    // 一级指针指向变量
    level_1 = &value;
    // 二级指针指向一级指针
    level_2 = &level_1;
    // 三级指针指向二级指针
    level_3 = &level_2;

    printf("The value is %d\n", what_is_the_value(level_3));    // The value is 1001

    return 0;
}

例102:尝试修改字符串常量

#include <stdio.h>
#include <ctype.h>

/**
 * 将字符串转成大写
 * @Author dust_fall
 * @param  string    要转换的字符串地址
 * @return           返回字符串地址
 */
char *string_uppercase(char *string)
{
    char *starting_address;

    starting_address = string;

    while (*string)
        toupper(*string++);

    return(starting_address);
}

int main(int argc, char const *argv[])
{
    char *title = "Jamsa's 1001 C/C++ Tips";
    char *string;

    string = string_uppercase(title);
    printf("%s\n", string);     // Jamsa's 1001 C/C++ Tips
    printf("%s\n", string_uppercase("Arrays and Pointers"));    // Arrays and Pointers


    // 代码后是运行结果, 为什么没有成功?
    // 因为main中的是使用指针指向字符串常量, 存储在常量存储区, 而常量存储区的内容是无法修改的

    return 0;
}

例103:使用函数指针做参数,调用不同函数

#include <stdio.h>

/**
 * 根据第三个参数传入的函数指针调用不同函数, 内部函数的参数是a,b
 * 这里编译会报错, 稍微改动一下就行
 */
int get_result(int a, int b, int (*compare)())
{
    return(compare(a, b));  
}
 

int max(int a, int b)
{
    printf("In max\n");

    return((a > b) ? a: b);
}

int min(int a, int b)
{
    printf("In min\n");

    return((a < b) ? a: b);
}

int main(int argc, char const *argv[])
{
    int result;

    result = get_result(1, 2, &max);
    printf("Max of 1 and 2 is %d\n", result);   // Max of 1 and 2 is 2
   
    result = get_result(1, 2, &min);
    printf("Min of 1 and 2 is %d\n", result);   // Min of 1 and 2 is 1

    return 0;
}

例104:使用库函数lfind查找数组元素

#include <stdio.h>
#include <stdlib.h>

/**
 * 标准库中的顺序查找函数
 * 函数原型void *lfind(const void *key, const void *base, size_t num, size_t size, int (*cmp)(const void *, const void *));
 * key 指向要查找的元素
 * base 指向进行查找的数组
 * num 数组中元素的个数
 * size 数组中每个元素的大小,一般用sizeof()表示
 * cmp 比较两个元素的函数,定义比较规则。需要注意的是,查找数组必须是经过预先排序的,而排序的规则要和比较子函数cmp的规则相同。
 * 如果找到元素则返回指向该元素的指针,否则返回NULL
 */

// 自定义比较函数,相等就返回0
int compare_int(int *a, int *b)
{
    return(*a - *b);
}

int compare_float(float *a, float *b)
{
    return((*a == *b) ? 0: 1);
}

int main(int argc, char const *argv[])
{
    int int_values[] = {1, 3, 2, 4, 5}; 
    float float_values[] = {1.1, 3.3, 2.2, 4.4, 5.5};  
   
    int *int_ptr, int_value = 2, elements = 5;
    float *float_ptr, float_value = 33.3;

    int_ptr = lfind(&int_value, int_values, &elements, sizeof(int), (int (*) (const void *, const void *)) compare_int);

    if (*int_ptr)
        printf("Value %d found\n", int_value);
    else 
        printf("Value %d not found\n", int_value);

    float_ptr = lfind(&float_value, float_values, &elements, sizeof(float), (int (*) (const void *, const void *)) compare_float);
   
    if (*float_ptr)
        printf("Value %3.1f found\n", float_value);
    else 
        printf("Value %3.1f not found\n", float_value);

    return 0;
}

例105:使用库函数lsearch查找数组元素

#include <stdlib.h>
#include <stdio.h>

/**
 * lsearch和上面的lfind差不多
 * 但lsearch在找不到元素后, 会把元素加入数组, 而lfind什么都不做
 */
int compare_int(int *a, int *b)
{
    return(*a - *b);
}

int compare_float(float *a, float *b)
{
    return((*a == *b) ? 0: 1);
}

int main(int argc, char const *argv[])
{
    int int_values[10] = {1, 3, 2, 4, 5}; 
    int *int_ptr, int_value = 1001, elements = 5, i;

    printf("Array contents before search\n");
    for (i = 0; i < elements; i++)
        printf("%d ", int_values[i]);   // 1 3 2 4 5
   
    int_ptr = lsearch(&int_value, int_values, &elements, sizeof(int), (int (*) (const void *, const void *)) compare_int);

    printf("\nArray contents after search\n");
    for (i = 0; i < elements; i++)
        printf("%d ", int_values[i]);   // 1 3 2 4 5 1001

    return 0;
}

例106:实现快速排序算法

#include <stdio.h>
#include <stdlib.h>

/**
 * 快速排序函数 - 选定一值, 左右夹击, 分区排序
 * @Author dust_fall
 * @param  array     要排序的数组
 * @param  first     要排序的首位置
 * @param  last      要排序的末位置
 */
void quick_sort(int array[], int first, int last)
{
    int temp, low, high, list_separator;    
   
    low = first;
    high = last;
    // 一个指定元素
    list_separator = array[(first + last) / 2];

    do {
        // 找到从左到右第一个大于等于指定数的下标
        while (array[low] < list_separator)
            low++;

        // 找到从右到左第一个小于等于指定数的下标
        while (array[high] > list_separator)
            high--;
   
        // 交换
        if (low <= high)
        {  
            temp = array[low];
            array[low++] = array[high];
            array[high--] = temp;
        }
    } while (low <= high);

    if (first < high)
        quick_sort(array, first, high);

    if (low < last)
        quick_sort(array, low, last);
}

int main(int argc, char const *argv[])
{
    int values[100], i; 

    for (i = 0; i < 100; i++)
        values[i] = rand() % 100;

    quick_sort(values, 0, 99);

    for (i = 0; i < 100; i++)
        printf("%d ", values[i]);
    
    // 关于快速排序算法这里不多解释, 那是另一篇博客的事了
    return 0;
}

例107:使用标准库中的快速排序函数

#include <stdlib.h>
#include <stdio.h>

int compare_int(int *a, int *b)
{
    return(*a - *b);
}

int compare_float(float *a, float *b)
{
    if (*a < *b)
        return(-1);
    else if (*a == *b)
        return(0);
    else
        return(1);
}

int main(int argc, char const *argv[])
{
    int int_values[] = {51, 23, 2, 44, 45}; 
    float float_values[] = {21.1, 13.3, 22.2, 34.4, 15.5};  
   
    int elements = 5, i;
   
    qsort(int_values, elements, sizeof(int), (int (*) (const void *, const void *)) compare_int);

    for (i = 0; i < elements; i++) 
        printf("%d ", int_values[i]);

    putchar('\n');

    qsort(float_values, elements, sizeof(float), (int (*) (const void *, const void *)) compare_float);
   
    for (i = 0; i < elements; i++)
        printf("%4.1f ", float_values[i]);
    
    return 0;
}

例108:实现选择排序算法

#include <stdio.h>
#include <stdlib.h>

/**
 * 选择排序函数 - 第i次循环找到第i+1小的元素放在第i个位置(i从0开始)
 * @Author dust_fall
 * @param  array     要排序的数组
 * @param  size      数组大小
 */
void selection_sort(int array[], int size)
{
    int temp, current, j;

    for (current = 0; current < size; current++) 
        for (j = current + 1; j < size; j++)
            if (array[current] > array[j])
            {
                temp = array[current];
                array[current] = array[j];
                array[j] = temp;
            }
}


int main(int argc, char const *argv[])
{
    int values[30], i; 

    for (i = 0; i < 30; i++)
        values[i] = rand() % 100;

    selection_sort(values, 30);

    for (i = 0; i < 30; i++)
        printf("%d ", values[i]);

    return 0;
}

例109:实现希尔排序算法

#include <stdio.h>
#include <stdlib.h>

/**
 * 希尔排序函数 - 分组(间隔通常为长度一半), 组内排序, 重复以上过程
 * @Author dust_fall
 * @param  array     要排序的数组
 * @param  size      数组大小
 */
void shell_sort(int array[], int size)
{
    int temp, gap, i, exchange_occurred;
        
    // 首次分组间隔
    gap = size / 2;      

    do {
        do {
            exchange_occurred = 0;

            for (i = 0; i < size - gap; i++)
                if (array[i] > array[i + gap])
                {  
                    temp = array[i];
                    array[i] = array[i + gap];
                    array[i + gap] = temp;
                    exchange_occurred = 1;
                }
        } while (exchange_occurred);
    // 改变分组间隔(重新分组)
    } while (gap = gap / 2);
}

int main(int argc, char const *argv[])
{
    int values[50], i; 

    for (i = 0; i < 50; i++)
        values[i] = rand() % 100;

    shell_sort(values, 50);

    for (i = 0; i < 50; i++)
        printf("%d ", values[i]);

    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值