库函数的介绍和使用

系统头文件中的库函数

stdio.h(标准输入输出库)

文件操作函数

  • 一:printf:格式化输出函数。
  • #include "stdio.h"
    int main()
    {    
        printf("hehe");
        return 0;
    }
  • 二:scanf:格式化输入函数。
  • #include "stdio.h"
    int main()
    {
        int n;
        scanf("%d", &n);
        printf("%d", n);
        return 0;
    }
  • 三:fopen、fclose
  • #include "stdio.h"
    
    int main()
    {
        //文件指针
        //声明指针类型
        //下定义--打开文件fopen
        FILE* pf = fopen("test.txt", "w");
              //打开形成的文件名字   打开方式
    
        //文件操作
        //判断是否成功打开--类似结构体
        if (pf == NULL)
        {
            perror("fopen");
            return 1;
        }
    
        //关闭文件类型
        fclose(pf);
        pf = NULL;
    
        return 0;
    }
    #include "stdio.h"
    
    struct S
    {
        char name[20];
        int age;
        float socre;
    };
    
    int main()
    {
        struct S s = {0};
        FILE* pf = fopen("test.jkl", "rb");
    
        if (pf == NULL)
        {
            perror("fopen");
            return 1;
        }
    读取pf里面的数据,每次读1个,开辟大小为结构体,然后放在s
    
        fread(&s,sizeof(struct S),1,pf);
        printf("%s %d %f\n", s.name, s.age, s.socre);
    
        fclose(pf);
        pf = NULL;
        return 0;
    }
四:fread
#include <stdio.h>  
#include <stdlib.h>  
  
int main() {  
    FILE *file;  
    long fileSize;  
    char *buffer;  
    size_t bytesRead;  
  
    // 打开文件  
    file = fopen("file.x", "rb");  
    if (file == NULL) {  
        fputs("Error opening file\n", stderr);  
        return 1; // 直接返回错误码  
    }  
  
    // 移动文件指针到文件末尾  
    fseek(file, 0, SEEK_END);  
    // 获取文件大小  
    fileSize = ftell(file);  
    // 重置文件指针到文件开头  
    rewind(file);  
  
    // 分配内存以存储文件内容  
    buffer = (char*)malloc(fileSize + 1); // +1 为了字符串的终结符 '\0'(尽管是二进制文件,但多分配一个字节可以避免后续作为字符串处理时的问题)  
    if (buffer == NULL) {  
        fputs("Error allocating memory\n", stderr);  
        fclose(file); // 清理已打开的文件  
        return 2; // 直接返回错误码  
    }  
  
    // 从文件中读取内容到buffer  
    bytesRead = fread(buffer, 1, fileSize, file);  
    if (bytesRead != fileSize) {  
        // 读取失败或未读取到预期数量的字节  
        fputs("Error reading file\n", stderr);  
        free(buffer); // 释放已分配的内存  
        fclose(file); // 清理已打开的文件  
        return 3; // 直接返回错误码  
    }  
  
    // 在这里,你可以对buffer中的数据进行处理...  
    // 但由于这是一个简化的示例,我们只是模拟了处理过程  
  
    // 清理资源  
    free(buffer);  
    fclose(file);  
  
    return 0; // 成功完成  
}
五:fwrite
#include "stdio.h"

struct S
{
    char name[20];
    int age;
    float socre;
};

int main()
{
    struct S s = {"zhagsan",20,95.5f};
    FILE* pf = fopen("test.jkl", "wb");

    if (pf == NULL)
    {
        perror("fopen");
        return 1;
    }

    fwrite(&s,sizeof(struct S),1,pf);

    fclose(pf);
    pf = NULL;
    return 0;
}
六:fprintf
#include "stdio.h"

struct S
{
    int n;
    float f;
    char arr[20];
};

int main()
{
    struct S s = { 100,3.14f,"zhangsan" };

    FILE* pf = fopen("test.jkl", "r");

    if (pf == NULL)
    {
        perror("fopen");
        return 1;
    }

    fprintf(pf,"%d %f %s\n",s.n,s.f,s.arr);

    fclose(pf);
    pf = NULL;

    return 0;
}
七:fscanf
#include "stdio.h"

struct S
{
    int n;
    float f;
    char arr[20];
};

int main()
{
    struct S s = {0};
    FILE* pf = fopen("test.jkl", "r");

    if (pf == NULL)
    {
        perror("fopen");
        return 1;
    }

    fscanf(pf,"%d %f %s",&(s.n),&(s.f),s.arr);

    fclose(pf);
    pf = NULL;
    return 0;
}

stdlib.h(标准库函数)

内存分配和释放函数

  • 一:malloc开辟一个内存
    Point*points=(Point *)malloc(sizeof(Point))
    
    返回值        返回类型        开辟字节大小
    
    如果开辟字节大小是可用数据来表示的话,可以直接写数字上去 eg int len1 = strlen(s1);
    
    char* temp = (char*)malloc(2 * len1 + 1*sizeof(char));     ---char 是一个字节,所以可以简化成下面这段代码,+1是为了给”\0”留一个位置
    
    char* temp = (char*)malloc(2 * len1 + 1);

    A.malloc函数向内存申请一块连续的空间,并返回起始地址 B.malloc申请空间失败,返回NULL指针 C.malloc可以向内存申请0字节的空间(calloc也差不多)

  • #include "stdio.h"
    #include "stdlib.h"
    
    int main()
    {
        char* str;
        str = (char*)malloc(sizeof(char));
    
        if (str == NULL)
        {
            return;
        }
    
        free(str);
    
        return 0;
    }
  • 二:calloc开辟多个内存
    Int sum;
    
    Scanf(“%d”,&sum);
    
    Point*points=(Point *)calloc(num,sizeof(Point))//定义5个空间,每一个空间的大小sizeof(Point)个字节
  • #include "stdio.h"
    #include "stdlib.h"
    
    int main()
    {
        char* str;
        int i;
        scanf("%d", &i);
        str = (char*)calloc(i,sizeof(char));
    
        if (str == NULL)
        {
            return;
        }
    
        free(str);
    
        return 0;
    }
    三:realloc修改内存空间
    Point*points/pa1=(Point*/int*)realloc(Point*points,28);

    表达为 将Point*points修改为28个字节空间大小

    开辟空间的三种可能:1.在原来基础上开辟 2.在新的第方式开辟,并且把旧的值传进去,释放掉原来的开辟空间 3.开辟了空指针,需要进行判断并且用一个临时指针来接受
  • Int *ljl=(Point*/int*)realloc(Point*points,28);
    
    If(ljl != NULL)
    
    {     Point*points/pa1=ljl};
  • 四:  free释放

    Free(Point*points/pa1)

    用上述的进行设置的动态空间,需要用free去释放,不然会内存泄露。

  • 程序终止函数。

  • 一:exit
  • #include <stdio.h>  
    #include <stdlib.h>  
      
    int main() {  
        // 假设这里有一些条件判断  
        int jkl= 1; // 假设条件不满足,我们想要退出程序  
      
        if (jkl) {  
            printf("条件不满足,程序将退出。\n");  
            exit(1); // 退出程序,并返回1表示错误  
        }  
      
        // 如果条件满足,程序将继续执行下面的代码  
        // 但在这个例子中,由于条件被设置为1,所以下面的代码不会被执行  
        printf("条件满足,程序继续执行。\n");  
      
        // 正常情况下,程序会在main函数末尾隐式地通过返回0来退出  
        // 但由于我们调用了exit,所以程序会在那里提前退出  
      
        return 0; // 这行代码实际上在这个例子中不会被执行  
    }

  • 二:abort
  • #include <stdio.h>  
    #include <stdlib.h>  
      
    int main() {  
        // 假设这里有一些条件判断  
        int jkl= 1; // 假设发生了某种错误,我们想要异常终止程序  
      
        if (jkl) {  
            printf("发生严重错误,程序将异常终止。\n");  
            abort(); // 异常终止程序  
        }  
      
        // 如果没有错误发生,程序将继续执行下面的代码  
        // 但在这个例子中,由于设置了jkl为1,所以下面的代码不会被执行  
        printf("程序正常运行。\n");  
      
        // 正常情况下,程序会在main函数末尾隐式地返回0  
        // 但由于我们调用了abort,所以程序会在那里提前异常终止  
      
        return 0; // 这行代码在这个例子中不会被执行  
    }

  • 随机数生成函数

  • rand,srand
  • #include <stdio.h>  
    #include <stdlib.h>  
    #include <time.h>  
      
    int main() {  
        // 使用当前时间作为随机数生成的种子  
        srand((unsigned)time(NULL));  
      
        // 生成并打印10个随机数  
        for(int i = 0; i < 10; i++) {  
            // rand() 函数返回一个伪随机数,其值在 0 到 RAND_MAX 之间  
            // RAND_MAX 是一个在 <stdlib.h> 中定义的常量,表示 rand() 函数能返回的最大值  
            printf("%d\n", rand());  
              
            // 如果你想要一个范围内的随机数,比如 1 到 100,你可以这样做:  
            // printf("%d\n", rand() % 100 + 1);  
        }  
      
        return 0;  
    }

string.h(字符串处理函数)

一:strcpy

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

int main()
{
    char str1[] = "hello";
    char str2[40];
    //将str1复制到str2中
    strcpy(str2, str1);
    printf("str1: %s\nstr2: %s\n", str1, str2);
    return 0;
}

二:strnpy

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

int main ()
{
  char str1[]= "To jkl";
  char str2[40];
  char str3[40];

  strncpy ( str2, str1, sizeof(str2) );

  puts (str2);

  return 0;
}

三:strcat

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

int main()
{
    char str[30];
    strcpy(str, "holle");
    strcat(str, "world");
    puts(str);
    return 0;
}

四:strcmp

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

int main()
{
    char key[] = "5";
    char j[10];
    do {
        printf("Guess my favorite number in 1-10? ");
        fflush(stdout);
        scanf("%79s", j);
    } while (strcmp(key, j) != 0);
    puts("yes!");
    return 0;
}

五:strlen

#include "stdio.h"
#include "string.h"

int main()
{
    char str[] = "asf";
    int len = 0;

    len=strlen(str);

    printf("%d\n", len);

    return 0;
}   

六:strlwr

#include <stdio.h>  
#include <ctype.h> // 为了使用 tolower 函数  
  

void my_strlwr(char *str) {  
    while (*str) { // 遍历字符串直到遇到 '\0'  
        *str = tolower((unsigned char)*str); // 将当前字符转换为小写  
        str++; 
    }  
}  
  
int main() {  
    char str[] = "HELLO, WORLD!";  
    printf("Original: %s\n", str);  
    my_strlwr(str); // 调用自定义的 strlwr 函数  
    printf("Lowercase: %s\n", str);  
    return 0;  
}

七:strupr

#include <stdio.h>  
#include <ctype.h> // 为了使用 toupper 函数  

void strupr(char* str) {
    while (*str) {   
        *str = toupper((unsigned char)*str); // 将当前字符转换为大写  
        str++; 
    }
}

int main() {
    char str[] = "Hello, World!";
    printf("Original: %s\n", str);
    strupr(str);
    printf("Uppercase: %s\n", str);
    return 0;
}

八:strstr

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

int main()
{
    char str[] = "asdf";
    char* jkl;
    jkl = strstr(str, "a");
    if (jkl != NULL)
    {
        puts(str);
    }
    else
    {
        printf("no");
    }
        
    return 0;
}

math.h(数学计算函数)

一:sqrt

#include <stdio.h>  
#include <math.h>  

double jkl(double x) {
    return sqrt(x);
}

int main() {
    double number = 9.0;
    double result = jkl(number);
    printf("%.2f\n",result);
    return 0;
}

二:sin,cos,tan

#include <stdio.h>  
#include <math.h> // 引入math.h以使用sin函数,但我们不直接使用M_PI  

// 定义一个近似的π值  
#define PI 3.141592653589793  

// 声明一个函数,它接受角度(以度为单位),将其转换为弧度,并返回其正弦值  
double sinDegrees(double degrees) {
    // 将度转换为弧度  
    double radians = degrees * (PI / 180.0);
    // 使用标准库的sin函数计算正弦值  
    return sin/cos/tan(radians);
}

int main() {
    // 计算45度的正弦值  
    double angleDegrees = 45.0;
    double sineValue = sinDegrees(angleDegrees);

    printf("The sine of %.2f degrees is %.6f\n", angleDegrees, sineValue);

    return 0;
}

三:exp

#include <stdio.h>  
  
// 定义一个简单的exp函数,使用泰勒级数的前几项来近似  
double simple_exp(double x) {  
    // 定义泰勒级数的前几项系数,这里只取了前5项(实际上可能需要更多项以提高精度)  
    // 注意:e^x = 1 + x + x^2/2! + x^3/3! + ...  
    double term = 1.0; // 第一项为1  
    double sum = 1.0; // 初始和也为1(因为第一项就是1)  
    double factorial = 1.0; // 阶乘,初始化为1  
  
    for (int i = 1; i < 5; ++i) { // 循环4次,因为我们已经有了第一项  
        factorial *= i; // 计算阶乘  
        term *= x / factorial; // 计算当前项的值  
        sum += term; // 累加到总和中  
    }  
  
    return sum;  
}  
  
int main() {  
    double x = 1.0;  
    double result = simple_exp(x);  
    printf("exp(%f) ≈ %f\n", x, result);  
  
    return 0;  
}

四:log

#include <stdio.h>  
#include <math.h> // 用于exp函数,仅用于验证  
  
// 使用二分查找法近似计算自然对数log(x)  
double simple_log(double x, double epsilon) {  
    // 假设x > 0,因为对数函数的定义域是正数  
    if (x <= 0) {  
        return -1.0; // 返回错误值  
    }  
  
    // 初始猜测值(这里简单地使用x-1,但通常需要更好的初始猜测)  
    double low = 0.0;  
    double high = x; // 对于自然对数,一个合理的上限是x本身(因为e^x >= x对所有x成立)  
    double mid;  
  
    while (high - low > epsilon) { // 当区间大小小于epsilon时停止迭代  
        mid = (low + high) / 2.0;  
        double exp_mid = exp(mid);  
  
        if (exp_mid < x) {  
            low = mid;  
        } else {  
            high = mid;  
        }  
  
        // 注意:上面的二分查找有一个问题,因为它没有处理exp_mid == x的情况,  
        // 这在实数运算中几乎不可能发生,但理论上应该处理这种情况以避免无限循环。  
        // 在实际应用中,你可能需要更复杂的逻辑来确保收敛。  
    }  
  
    // 返回中点作为近似值  
    return mid;  
}  
  
int main() {  
    double x = 2.71828; // e的近似值  
    double epsilon = 0.0001; // 精度要求  
    double result = simple_log(x, epsilon);  
    printf("log(%f) ≈ %f\n", x, result);  
  
    // 验证结果(理论上应该接近1,因为log(e) = 1)  
    printf("Error: %f\n", fabs(result - 1.0));  
  
    return 0;  
}

五:pow

#include <stdio.h>  
  
// 简单的pow函数实现,使用循环  
double simple_pow(double x, int y) {  
    double result = 1.0;  
    for (int i = 0; i < y; i++) {  
        result *= x;  
    }  
    return result;  
}  
  
int main() {  
    double base = 2.0;  
    int exponent = 3;  
    double result = simple_pow(base, exponent);  
    printf("%.2f to the power of %d is %.2f\n", base, exponent, result);  
  
    return 0;  
}

time.h(时间日期处理函数)

一:time

#include <stdio.h>  
#include <time.h> // 包含time_t和时间操作函数的定义  
  
// 计算两个时间点之间的差异(以秒为单位)  
double calculate_time_difference(time_t start_time, time_t end_time) {  
    // 简单地返回两个时间点的差  
    return difftime(end_time, start_time);  
}  
  
int main() {  
    // 获取当前时间  
    time_t now = time(NULL);  
  
    // 假设过了一段时间(这里我们模拟为5秒)  
    time_t later = now + 5;  
  
    // 计算时间差  
    double difference = calculate_time_difference(now, later);  
  
    // 打印结果  
    printf("The time difference is: %.2f seconds\n", difference);  
  
    return 0;  
}

二:ctime

#include <stdio.h>  
#include <time.h>  
  
// 使用ctime来显示可读的时间字符串  
void simple_ctime_display(time_t time_value) {  
    // 使用ctime将time_t值转换为可读的字符串,并打印它  
    // 注意:ctime返回的字符串指向一个静态分配的缓冲区,这意味着连续调用可能会覆盖之前的结果  
    char* time_str = ctime(&time_value);  
    printf("The time is: %s", time_str);  
}  
  
int main() {  
    // 获取当前时间  
    time_t now = time(NULL);  
  
    // 调用我们自定义的函数来显示时间  
    simple_ctime_display(now);  
  
    return 0;  
}

三:strftime

#include <stdio.h>  
#include <time.h>  
#include <string.h>  
  
// 封装strftime的函数,用于格式化当前时间  
void format_current_time(char *buffer, size_t bufsize, const char *format) {  
    // 获取当前时间  
    time_t now = time(NULL);  
    // 使用strftime将时间格式化为字符串  
    strftime(buffer, bufsize, format, localtime(&now));  
}  
  
int main() {  
    // 准备一个缓冲区来存储格式化后的时间字符串  
    char formatted_time[80];  
  
    // 调用封装的函数,使用"%Y-%m-%d %H:%M:%S"作为时间格式  
    format_current_time(formatted_time, sizeof(formatted_time), "%Y-%m-%d %H:%M:%S");  
  
    // 打印格式化后的时间  
    printf("Formatted time: %s\n", formatted_time);  
  
    return 0;  
}

ctype.h(字符类型处理函数)

一:isalpha

#include <stdio.h>  
#include <stdbool.h> // 为了使用bool, true, false  
  
// 自定义的isalpha函数  
bool my_isalpha(char c) {  
    // ASCII码中,大写字母A-Z的范围是65-90,小写字母a-z的范围是97-122  
    if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z')) {  
        return true; // 是字母  
    } else {  
        return false; // 不是字母  
    }  
}  
  
int main() {  
    char testChar1 = 'a';  
    char testChar2 = '3';  
    char testChar3 = 'A';  
  
    printf("'%c' is an alphabet? %s\n", testChar1, my_isalpha(testChar1) ? "Yes" : "No");  
    printf("'%c' is an alphabet? %s\n", testChar2, my_isalpha(testChar2) ? "Yes" : "No");  
    printf("'%c' is an alphabet? %s\n", testChar3, my_isalpha(testChar3) ? "Yes" : "No");  
  
    return 0;  
}

二:isdigit

#include <stdio.h>  
#include <stdbool.h> // 为了使用bool, true, false  
  
// 自定义的isdigit函数  
bool my_isdigit(char c) {  
    // ASCII码中,数字0-9的范围是48-57  
    if (c >= '0' && c <= '9') {  
        return true; // 是数字  
    } else {  
        return false; // 不是数字  
    }  
}  
  
int main() {  
    char testChar1 = '5';  
    char testChar2 = 'a';  
    char testChar3 = '0';  
  
    printf("'%c' is a digit? %s\n", testChar1, my_isdigit(testChar1) ? "Yes" : "No");  
    printf("'%c' is a digit? %s\n", testChar2, my_isdigit(testChar2) ? "Yes" : "No");  
    printf("'%c' is a digit? %s\n", testChar3, my_isdigit(testChar3) ? "Yes" : "No");  
  
    return 0;  
}

三:islower

#include <stdio.h>  
#include <stdbool.h> // 为了使用bool, true, false  
  
// 自定义的islower函数  
bool my_islower(char c) {  
    // ASCII码中,小写字母a-z的范围是97-122  
    if (c >= 'a' && c <= 'z') {  
        return true; // 是小写字母  
    } else {  
        return false; // 不是小写字母  
    }  
}  
  
int main() {  
    char testChar1 = 'a';  
    char testChar2 = 'A';  
    char testChar3 = '3';  
  
    printf("'%c' is lowercase? %s\n", testChar1, my_islower(testChar1) ? "Yes" : "No");  
    printf("'%c' is lowercase? %s\n", testChar2, my_islower(testChar2) ? "Yes" : "No");  
    printf("'%c' is lowercase? %s\n", testChar3, my_islower(testChar3) ? "Yes" : "No");  
  
    return 0;  
}

四:isupper

#include <stdio.h>  
#include <stdbool.h> // 为了使用bool, true, false  
  
// 自定义的isupper函数  
bool my_isupper(char c) {  
    // ASCII码中,大写字母A-Z的范围是65-90  
    if (c >= 'A' && c <= 'Z') {  
        return true; // 是大写字母  
    } else {  
        return false; // 不是大写字母  
    }  
}  
  
int main() {  
    char testChar1 = 'A';  
    char testChar2 = 'a';  
    char testChar3 = '3';  
  
    printf("'%c' is uppercase? %s\n", testChar1, my_isupper(testChar1) ? "Yes" : "No");  
    printf("'%c' is uppercase? %s\n", testChar2, my_isupper(testChar2) ? "Yes" : "No");  
    printf("'%c' is uppercase? %s\n", testChar3, my_isupper(testChar3) ? "Yes" : "No");  
  
    return 0;  
}

五:tolower

#include <stdio.h>  
  
// 自定义的tolower函数  
char my_tolower(char c) {  
    // ASCII码中,大写字母A-Z的范围是65-90  
    // 小写字母a-z的范围是97-122  
    // 大写字母转换为小写字母,只需要加上32(因为'a'-'A' = 32)  
    if (c >= 'A' && c <= 'Z') {  
        return c + 32; // 转换为小写字母  
    } else {  
        return c; // 不是大写字母,直接返回  
    }  
}  
  
int main() {  
    char testChar1 = 'A';  
    char testChar2 = 'a';  
    char testChar3 = '3';  
  
    printf("'%c' to lowercase: '%c'\n", testChar1, my_tolower(testChar1));  
    printf("'%c' to lowercase: '%c'\n", testChar2, my_tolower(testChar2));  
    printf("'%c' to lowercase: '%c'\n", testChar3, my_tolower(testChar3));  
  
    return 0;  
}

六:toupper

#include <stdio.h>  
  
// 自定义的toupper函数  
char my_toupper(char c) {  
    // ASCII码中,小写字母a-z的范围是97-122  
    // 大写字母A-Z的范围是65-90  
    // 小写字母转换为大写字母,只需要减去32(因为'A'-'a' = 32)  
    if (c >= 'a' && c <= 'z') {  
        return c - 32; // 转换为大写字母  
    } else {  
        return c; // 不是小写字母,直接返回  
    }  
}  
  
int main() {  
    char testChar1 = 'a';  
    char testChar2 = 'A';  
    char testChar3 = '3';  
  
    printf("'%c' to uppercase: '%c'\n", testChar1, my_toupper(testChar1));  
    printf("'%c' to uppercase: '%c'\n", testChar2, my_toupper(testChar2));  
    printf("'%c' to uppercase: '%c'\n", testChar3, my_toupper(testChar3));  
  
    return 0;  
}

errno.h(错误处理函数)

一:errno

#include <stdio.h>  
#include <errno.h>  
#include <string.h>  
  
// 自定义的错误码  
#define MY_SUCCESS 0  
#define MY_FAILURE -1  
  
// 模拟可能失败的操作的函数  
int my_operation(int param) {  
    // 假设param小于0时操作失败  
    if (param < 0) {  
        // 设置errno以指示错误类型  
        errno = EINVAL; // EINVAL是一个在<errno.h>中定义的错误码,表示无效参数  
        return MY_FAILURE;  
    }  
    // 操作成功  
    return MY_SUCCESS;  
}  
  
// 检查my_operation函数返回值的函数  
void check_operation(int result) {  
    if (result == MY_FAILURE) {  
        // 如果操作失败,打印错误信息  
        printf("Operation failed: %s\n", strerror(errno));  
    } else {  
        // 操作成功  
        printf("Operation succeeded.\n");  
    }  
}  
  
int main() {  
    // 尝试执行可能失败的操作  
    int result = my_operation(5);  // 应该成功  
    check_operation(result);  
  
    result = my_operation(-1);     // 应该失败  
    check_operation(result);  
  
    return 0;  
}

二:perror

#include <stdio.h>  
#include <errno.h>  
#include <string.h>  
  
// 自定义的perror函数  
void my_perror(const char *s) {  
    // 检查s是否为NULL,避免解引用空指针  
    if (s == NULL) {  
        fprintf(stderr, "Null pointer error\n");  
    } else {  
        // 使用strerror获取errno的错误描述  
        fprintf(stderr, "%s: %s\n", s, strerror(errno));  
    }  
}  
  
// 一个可能设置errno的函数  
void some_operation(int flag) {  
    if (flag) {  
        // 假设某些错误发生  
        errno = EINVAL; // 设置errno为无效参数错误  
    }  
}  
  
int main() {  
    printf("Before operation, errno is: %d\n", errno); // 通常应为0,除非之前已设置  
  
    some_operation(1); // 触发错误  
  
    my_perror("Operation failed"); // 使用自定义的perror函数  
  
    // 重置errno以避免影响后续调用  
    errno = 0;  
  
    printf("After resetting errno, errno is: %d\n", errno);  
  
    return 0;  
}

signal.h(信号处理函数)

一:signal

#include <stdio.h>  
#include <stdlib.h>  
#include <signal.h>  
#include <unistd.h>  
  
// 自定义的信号处理函数  
void signal_handler(int signum) {  
    printf("Caught signal %d\n", signum);  
  
    // 清理并退出  
    // 注意:在实际的程序中,你应该在这里执行必要的清理工作  
    // 然后退出程序,以避免不确定的行为  
    exit(signum);  
}  
  
int main() {  
    // 设置SIGINT信号的处理函数为signal_handler  
    signal(SIGINT, signal_handler);  
  
    // 模拟一个长时间运行的过程  
    printf("Waiting for signal...\n");  
    while (1) {  
        sleep(1); // 休眠一秒,等待信号  
    }  
  
    // 注意:由于上面的while循环是无限循环,并且我们没有在信号处理函数中调用exit,  
    // 这段代码实际上永远不会执行到这里。但是,为了完整性,我还是保留了它。  
    // 在真实的应用中,你应该在信号处理函数中处理退出逻辑。  
  
    return 0;  
}

二:raise

#include <stdio.h>  
#include <stdlib.h> // 为了使用exit  
  
// 假设的错误码  
#define MY_SUCCESS 0  
#define MY_ERROR_INVALID_PARAM -1  
#define MY_ERROR_GENERIC -2  
  
// 全局错误码(模拟异常对象)  
int my_errno = MY_SUCCESS;  
  
// 自定义的“raise”函数,实际上只是设置错误码并可能终止程序  
void my_raise(int error_code) {  
    my_errno = error_code;  
    fprintf(stderr, "Error: %d\n", error_code);  
    // 在这里,我们可以选择退出程序或进行其他错误处理  
    // 例如,exit(EXIT_FAILURE); 但这通常不是最佳实践  
    // 更好的做法是让调用者检查my_errno并据此处理错误  
}  
  
// 可能“抛出”错误的函数  
int divide(int numerator, int denominator) {  
    if (denominator == 0) {  
        my_raise(MY_ERROR_INVALID_PARAM); // “抛出”错误  
        return MY_ERROR_INVALID_PARAM; // 返回错误码  
    }  
    return numerator / denominator;  
}  
  
int main() {  
    int result = divide(10, 0);  
    if (result == MY_ERROR_INVALID_PARAM) {  
        // 处理错误  
        printf("Caught an error: division by zero.\n");  
    } else {  
        // 正常情况  
        printf("Result: %d\n", result);  
    }  
  
    // 假设我们有一个不同的函数,它也可能失败  
    result = some_other_function(); // 假设这个函数在某些条件下会调用my_raise  
    if (result == MY_ERROR_GENERIC) {  
        // 处理其他类型的错误  
        printf("Caught a generic error.\n");  
    }  
  
    return 0;  
}  
  
// 注意:some_other_function函数在这里没有定义,但它应该遵循类似的错误处理模式

  • 15
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值