C-语言学习(4)-----C语言基本库的使用

128 阅读5分钟

#####基本C库汇总

基本C库功能说明
#include <assert.h>assert 宏
#include <errno.h>errno
#include <ctype.h>判断字符相关的函数,tolower,toupper
#include <limits.h>定义各个类型极值的宏
#include <stdarg.h>可变参数宏va_list,va_start,va_end
#include <stddef.h>定义 size_t 和 NULL
#include <time.h>time 相关函数
#include <stdint.h>定义uin32_t 等定宽类型
#include <stdio.h>printf,scanf,File 相关函数,vprintf,vfprintf 等
#include <string.h>mem 相关函数,str 开头相关字符串操作函数
#include <stdlib.h>atoi,atof 等转换函数,strtod 等转换函数,rand随机数函数,malloc,calloc 内存分配函数
assert.h

提供了一个名为 assert 的宏,它可用于验证程序做出的假设,并在假设为假时输出诊断消息 如果表达式为 FALSE (0), 程序将报告错误,并终止执行;如果表达式不为 0(false),则继续执行后面的语句 assert 只在Debug版本中有作用,在release 版本中会被忽略

如果预先定义宏 #define NDEBUG ,assert 的错误将被忽略

#define NDEBUG 
#include <assert.h>
void testAssert() {

	uint32_t a = 11;
	assert(a > 100);
	assert(a == 100); // 会产生assert 错误
}

#####errno.h errno.h 头文件定义了整数变量 errno,在程序启动时,errno 设置为零,C 标准库中的特定函数修改它的值为一些非零值以表示某些类型的错误 strerror 位于 string.h 中,用于将错误码转换为字符串提示输出 perror 会自动打印出错误码字符串信息

#include <errno.h>
void testerrorNum() {
	printf("current error number: %d string:%s\n", errno, strerror(errno));

	errno = 5;
	printf("current error number: %d string:%s\n", errno, strerror(errno));
	perror("Got error message\n");

}

#####limits.h limits.h 头文件决定了各种变量类型的各种属性,定义在该头文件中的宏限制了各种变量类型(比如 char、int 和 long)的极限值

#include <limits.h>
void testlimits() {

	printf("The number of bits in a byte %d\n", CHAR_BIT); //char bits 

	printf("The minimum value of SIGNED CHAR = %d\n", SCHAR_MIN);//signed char min
	printf("The maximum value of SIGNED CHAR = %d\n", SCHAR_MAX); //signed char max
	printf("The maximum value of UNSIGNED CHAR = %d\n", UCHAR_MAX);//unsigned char max 

	printf("The minimum value of SHORT INT = %d\n", SHRT_MIN);//short min
	printf("The maximum value of SHORT INT = %d\n", SHRT_MAX);//short max

	printf("The minimum value of INT = %d\n", INT_MIN);// int min 
	printf("The maximum value of INT = %d\n", INT_MAX);// int max 

	printf("The minimum value of CHAR = %d\n", CHAR_MIN);// char min
	printf("The maximum value of CHAR = %d\n", CHAR_MAX);// char max

	printf("The minimum value of LONG = %ld\n", LONG_MIN);// long min
	printf("The maximum value of LONG = %ld\n", LONG_MAX);// long max

}

#####ctype.h ctype.h 头文件提供了一些函数,可用于测试和映射字符

#include <ctype.h>
void testCtype() {
	char a = 'c';
	printf("char isalnum %d\n", isalnum(a)); //是否为字母或者数字
	printf("char isalpha %d\n", isalpha(a)); // 是否是字母
	printf("char isdigit %d\n", isdigit(a));  // 是否是数字


	printf("char iscntrl %d\n", iscntrl(a)); // 是否是控制字符

	printf("char isgraph %d\n", isgraph(a));  // 是否有图形表示法
	printf("char islower %d\n", islower(a));  // 是否是小写字母
	printf("char isupper %d\n", isupper(a));  // 是否是大写字母

	printf("char isprint %d\n", isprint(a));  // 是否是可打印的
	printf("char ispunct %d\n", ispunct(a));  // 是否是标点符号字符
	printf("char isspace %d\n", isspace(a));  // 是否是空白字符

	printf("char to lower %c\n", tolower(a));  // 是否是空白字符
	printf("char to upper %c\n", toupper(a));  // 是否是空白字符

}

#####stddef.h stddef.h 头文件定义了各种变量类型和宏,这些定义中的大部分也出现在其它头文件中

  • size_t :这是无符号整数类型,它是 sizeof 关键字的结果
  • NULL:指向一个空指针

#####string.h 包含mem 开头的函数族和 字符串 str 开头的函数族

功能说明举例
mem 操作函数memcpy memset memcmp memchar
str 操作函数strcpy strncpy strlen strcmp strstr strchr strcat strncat strok
void testmemoperate() {
	// ==== test memset
	char ademoArray[100] = { 100 };
	printf("ademoArray init value: %d %d\n", ademoArray[10], ademoArray[20]);
	memset(ademoArray, 0, sizeof(ademoArray));
	
	// ==== test memcpy
	char* srcptr = "helloworld";
	memcpy(ademoArray, srcptr, strlen(srcptr));
	printf("ademoArray after copy %s \n", ademoArray);

	char* temptr = (char*)calloc(20, sizeof(char));
	memcpy(temptr,"helloworld", strlen("helloworld"));

	// ==== test memcmp
	if (memcmp(temptr, ademoArray, 20) == 0) {
		printf("temptr equals srcptr \n");
	} else {
		printf("temptr not equals srcptr \n");
	}

	char* chrptr = memchr(temptr, 'l', strlen("helloworld"));
	printf("memchr get char: %s addr:%p startaddr:%p", chrptr, chrptr, temptr);
}

#####stdarg.h stdarg.h 包含了可变参数宏,用于可变参数函数,可变参数的示例如下:

void _demo_va_func(char* format,...) 使用三个点省略号表示可变参数

可变参数用到以下宏函数: va_list类型的变量:这个变量是指向参数地址的指针,因为得到参数的地址之后,再结合参数的类型,才能得到参数的值 void va_start(va_list arg_ptr, prev_param) :以固定参数的地址为起点确定变参的内存起始地址,获取第一个参数的首地址 type va_arg(va_list arg_ptr, type):获取下一个参数的地址 根据传入参数类型决定返回值类型 void va_end(va_list arg_ptr); :将 arg_ptr 指针置0

使用可变参数宏的一般步骤:

  • 定义va_list
  • 使用va_start 获取指向第一个可变参数的指针
  • 使用va_arg 获取每个可变参数
  • 使用va_end 结束将 arg_ptr 指针置0

具体如下,功能是打印出可变参数的两个函数

// use  change para to implment this function 
// use  vprintf to  implment  char* format,... 
void _demo_va_func(char* format,...)
{
     char * parg;
	 va_list arg_ptr; 
	 va_start(arg_ptr, format); 
#if (debug == 1)
     printf("content %s \n",format);
     printf("arg_ptr is: %s \n",va_arg(arg_ptr,char*));
     printf("arg_ptr is: %s \n",va_arg(arg_ptr,char*));
#endif
     va_end(arg_ptr);

     va_start(arg_ptr, format); 
     vprintf(format,arg_ptr);
	 va_end(arg_ptr);
}

使用 vprintf 实现printf的功能,使用 vfprintf 就可以将函数输出直接打印到文件中

void _demo_va_test(char* format,...)
{
	 va_list arg_ptr; 
	 va_start(arg_ptr, format); 
     vprintf(format,arg_ptr);
	 va_end(arg_ptr);
}



// 基于这个函数 可以实现将 可变参数打印在 文件之中 的功能
void _demo_va_file(FILE *stream,char* format,...)
{
	 va_list arg_ptr; 
	 va_start(arg_ptr, format); 
     vfprintf(stream,format,arg_ptr);
	 va_end(arg_ptr);
}

int main(int argc,char * argv[])
{
    FILE* fp = NULL;
    MI_PRINT("This is my Va args demo! %s builddate:%s %s\n",__FUNCTION__,__DATE__,__TIME__);
    _demo_va_func("This is say I am working %s %s \n",__DATE__,__TIME__);
   
     fp  = fopen("demo.log","w+");
     _demo_va_file(fp ,"build time %s %s \n",__DATE__,__TIME__);
	 _demo_va_file(fp ,"hello world \n");

	
     return 0;
}

注意: 在定义可变参数的宏时,使用 ##VA_ARGS 代表可变的参数,

#define M_PRINT(fmt,...) printf("[%s] line:%d " fmt,__FUNCTION__, __LINE__, ##__VA_ARGS__)
M_PRINT("test demo print %d", 2);