首页
前端面试题
前端报错总结
电子书
更多
插件下载
Search
1
JavaScript基础(二)操作符 流程控制
42 阅读
2
HTML基础
20 阅读
3
Vue基础
17 阅读
4
wctype.h
14 阅读
5
Vue2(知识点)
13 阅读
默认分类
HTML CSS
HTML基础
CSS
HTML5 CSS3
javaScript
javaScript基础
javaScript高级
Web APIs
jQuery
js小总结
WEB开发布局
Vue
PS切图
数据可视化
Git使用
Uniapp
c语言入门
标准库
嵌入式
登录
Search
liuxiaobai
累计撰写
108
篇文章
累计收到
12
条评论
首页
栏目
默认分类
HTML CSS
HTML基础
CSS
HTML5 CSS3
javaScript
javaScript基础
javaScript高级
Web APIs
jQuery
js小总结
WEB开发布局
Vue
PS切图
数据可视化
Git使用
Uniapp
c语言入门
标准库
嵌入式
页面
前端面试题
前端报错总结
电子书
插件下载
搜索到
104
篇与
的结果
2024-12-12
C基础
目录c基础数据类型说明volatile指针函数指针函数指针数组指针数组数组指针指针的指针main函数的返回值const浮点数存储方式c题目printf返回值enum枚举类型可变参数函数链表排序算法选择排序插入排序希尔排序冒泡排序快速排序hash算法hash构造方法hash冲突及解决常用的hash函数c基础数据类型说明volatile指针constmain函数的返回值浮点数存储方式数据类型说明数据类型16位平台32位平台64位平台char1 字节1 字节1 字节pointer2 字节4 字节8 字节short2 字节2 字节2 字节int2 字节4 字节4 字节float4 字节4 字节4 字节double8 字节8 字节8 字节long4 字节4 字节8 字节long long8 字节8 字节8 字节volatilevolatile 指出变量是随时可能发生变化的,每次使用它的时候必须从变量的地址中读取,因而编译器生成的汇编代码会重新从变量的地址读取数据。并行设备的硬件寄存器,一个中断服务子程序中会访问到的非自动变量(Non-automatic variables),可以使用关键区保护多线程应用中被几个任务共享的变量,可以关闭系统调度指针函数指针int (*fun)(int *a);函数指针数组int (*fun[10])(int *data, int size);使用方法:int (*sort_fun[5])(int *data, int size) = { quick_sort, /* 快速排序 */ insert_sort, /* 插入排序 */ bubble_sort, /* 冒泡排序 */ heap_sort, /* 堆排序 */ selection_sort /* 选择排序 */ }; // 或者 sort_fun[0] = quick_sort; sort_fun[1] = insert_sort;指针数组int *a[10];数组指针/* a为指向含10个元素的一维数组的指针变量, * ()优先级高,说明a是一个指针,指向一个整型的一维数组. * a+1时,a要跨过10个整型数据的长度 */ int (*a)[10];指针的指针int **a;main函数的返回值0 表示程序正常退出负数表示程序异常退出constconst T定义一个常量,声明的同时必须进行初始化。一旦声明,这个值将不能被改变。const int constInt = 10; //正确 constInt = 20; //错误,常量值不可被改变 const int constInt3; //错误,未被初始化const T*指向常量的指针,不能用于改变其所指向的对象的值。const int i = 5; const int i2 = 10; const int* pInt = &i; //正确,指向一个const int对象,即i的地址 //*pInt = 10; //错误,不能改变其所指缶的对象 pInt = &i2; //正确,可以改变pInt指针本身的值,此时pInt指向的是i2的地址 const int* p2 = new int(8); //正确,指向一个new出来的对象的地址 delete p2; //正确 //int* pInt = &i; //错误,i是const int类型,类型不匹配,不能将const int * 初始化为int * int nValue = 15; const int * pConstInt = &nValue; //正确,可以把int *赋给const int *,但是pConstInt不能改变其所指向对象的值,即nValue *pConstInt = 40; //错误,不能改变其所指向对象的值const int 与int const的区别指针本身就是一种对象,把指针定义为常量就是常量指针,也就是int const的类型,也可以写成int const,声明时必须初始化。int nValue = 10; int* const p = &nValue; int *const p2 = &nValue; //const int* 指针指向的对象不可以改变,但指针本身的值可以改变;int* const 指针本身的值不可改变,但其指向的对象可以改变。 int nValue1 = 10; int nValue2 = 20; int* const constPoint = &nValue1; //constPoint = & nValue2; //错误,不能改变constPoint本身的值 *constPoint = 40; //正确,可以改变constPoint所指向的对象,此时nValue1 = 40 const int nConstValue1 = 5; const int nConstValue2 = 15; const int* pPoint = &nConstValue1; //*pPoint = 55; //错误,不能改变pPoint所指向对象的值 pPoint = &nConstValue2; //正确,可以改变pPoint指针本身的值,此时pPoint邦定的是nConstValue2对象,即pPoint为nConstValue2的地址const int* const 是一个指向常量对象的常量指针,即不可以改变指针本身的值,也不可以改变指针指向的对象。const int nConstValue1 = 5; const int nConstValue2 = 15; const int* const pPoint = &nConstValue1; //*pPoint = 55; //错误,不能改变pPoint所指向对象的值 //pPoint = &nConstValue2; //错误,不能改变pPoint本身的值const助记方法把一个声明从右向左读。( * 读成 pointer to )char * const cp; // cp is a const pointer to char const char * p; // p is a pointer to const char; char const * p; // 同上,因为C++里面没有const*的运算符,所以const只能属于前面的类型。C++标准规定,const关键字放在类型或变量名之前等价的。结论:char * const cp // 定义一个指向字符的指针常数,即const指针 const char* p // 定义一个指向字符常数的指针 char const* p // 等同于const char* p const char ** // 是一个指向指针的指针,那个指针又指向一个字符串常量。 char ** // 也是一个指向指针的指针,那个指针又指向一个字符串变量。浮点数存储方式float 占用4个字节,32bits 符号位 指数位 尾数部分 1 bits 8 bits 23 bits double 占用8字节,64bits 符号位 指数位 尾数部分 1 bits 11 bits 52 bits c题目printf返回值enum枚举类型可变参数函数printf返回值#include <stdio.h> int main() { int i = 43; printf("%d\n", printf("%d", printf("%d", i))); return 0; }输出:4321printf返回值是输出字符的个数(不包括字符串结尾\x00)enum枚举类型#include <stdio.h> int main() { enum color{ RED, BLUE, GREEN = -2, YELLOW, PINK }; printf("%d %d\n", BLUE, PINK); return 0; }输出:1 0enum默认是从0开始的,所以RED = 0, BLUE = 1, GREEN = -2, YELLOW = -1, PINK = 0;可变参数函数#include "stdarg.h" char buf[512] = {0}; int func(const char *fmt, ...) { va_list args; va_start(args, fmt); vsprintf(buf, fmt, args); va_end(args); }大小端区分union data { int a; char b; }; struct def { union data mine; }; struct def endian; int main(int argc, char **argv) { endian.mine.a = 0x12345678; printf("%02X\n", endian.mine.b); return 0; } /*打印 78 说明是小端, 12 说明是大端 */链表//////////////////////////////////////////// //单链表的初始化,建立,插入,查找,删除。// //Author:Wang Yong // //Date: 2010.8.19 // //////////////////////////////////////////// #include <stdio.h> #include <stdlib.h> typedef int ElemType; //////////////////////////////////////////// //定义结点类型 typedef struct Node { ElemType data; //单链表中的数据域 struct Node *next; //单链表的指针域 }Node,*LinkedList; //////////////////////////////////////////// //单链表的初始化 LinkedList LinkedListInit() { Node *L; L = (Node *)malloc(sizeof(Node)); //申请结点空间 if(L == NULL) //判断是否有足够的内存空间 printf("申请内存空间失败/n"); L->next = NULL; //将next设置为NULL,初始长度为0的单链表 } //////////////////////////////////////////// //单链表的建立1,头插法建立单链表 LinkedList LinkedListCreatH() { Node *L; L = (Node *)malloc(sizeof(Node)); //申请头结点空间 L->next = NULL; //初始化一个空链表 ElemType x; //x为链表数据域中的数据 while(scanf("%d",&x) != EOF) { Node *p; p = (Node *)malloc(sizeof(Node)); //申请新的结点 p->data = x; //结点数据域赋值 p->next = L->next; //将结点插入到表头L-->|2|-->|1|-->NULL L->next = p; } return L; } //////////////////////////////////////////// //单链表的建立2,尾插法建立单链表 LinkedList LinkedListCreatT() { Node *L; L = (Node *)malloc(sizeof(Node)); //申请头结点空间 L->next = NULL; //初始化一个空链表 Node *r; r = L; //r始终指向终端结点,开始时指向头结点 ElemType x; //x为链表数据域中的数据 while(scanf("%d",&x) != EOF) { Node *p; p = (Node *)malloc(sizeof(Node)); //申请新的结点 p->data = x; //结点数据域赋值 r->next = p; //将结点插入到表头L-->|1|-->|2|-->NULL r = p; } r->next = NULL; return L; } //////////////////////////////////////////// //单链表的插入,在链表的第i个位置插入x的元素 LinkedList LinkedListInsert(LinkedList L,int i,ElemType x) { Node *pre; //pre为前驱结点 pre = L; int tempi = 0; for (tempi = 1; tempi < i; tempi++) pre = pre->next; //查找第i个位置的前驱结点 Node *p; //插入的结点为p p = (Node *)malloc(sizeof(Node)); p->data = x; p->next = pre->next; pre->next = p; return L; } //////////////////////////////////////////// //单链表的删除,在链表中删除值为x的元素 LinkedList LinkedListDelete(LinkedList L,ElemType x) { Node *p,*pre; //pre为前驱结点,p为查找的结点。 p = L->next; while(p->data != x) //查找值为x的元素 { pre = p; p = p->next; } pre->next = p->next; //删除操作,将其前驱next指向其后继。 free(p); return L; } ///////////////////////////////////////////// int main() { LinkedList list,start; /* printf("请输入单链表的数据:"); list = LinkedListCreatH(); for(start = list->next; start != NULL; start = start->next) printf("%d ",start->data); printf("/n"); */ printf("请输入单链表的数据:"); list = LinkedListCreatT(); for(start = list->next; start != NULL; start = start->next) printf("%d ",start->data); printf("/n"); int i; ElemType x; printf("请输入插入数据的位置:"); scanf("%d",&i); printf("请输入插入数据的值:"); scanf("%d",&x); LinkedListInsert(list,i,x); for(start = list->next; start != NULL; start = start->next) printf("%d ",start->data); printf("/n"); printf("请输入要删除的元素的值:"); scanf("%d",&x); LinkedListDelete(list,x); for(start = list->next; start != NULL; start = start->next) printf("%d ",start->data); printf("/n"); return 0; }排序算法选择排序插入排序希尔排序冒泡排序快速排序排序算法有: 选择排序 快速排序 希尔排序 冒泡排序 插入排序 堆排序 归并排序 排序算法比较:选择排序选择排序是一种简单直观的排序算法,无论什么数据进去都是 O(n²) 的时间复杂度。所以用到它的时候,数据规模越小越好。唯一的好处可能就是不占用额外的内存空间了吧。时间复杂度平均: O(n2) 最好: O(n2) 最坏:O(n2)空间复杂度O(1)算法步骤首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。重复第二步,直到所有元素均排序完毕。动图演示/* 直接选择排序 */ void selection_sort(int n) { for (int i = 0; i < n - 1; i++) { int min = i; for (int j = i + 1; j < n; j++) { if (x[j] < x[min]) { min = j; } } if (min != i) { swap(x,i,min); } } }插入排序插入排序的代码实现虽然没有冒泡排序和选择排序那么简单粗暴,但它的原理应该是最容易理解的了,因为只要打过扑克牌的人都应该能够秒懂。插入排序是一种最简单直观的排序算法,它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。插入排序和冒泡排序一样,也有一种优化算法,叫做拆半插入。时间复杂度平均:O(n2) 最好:O(n) 最坏:O(n2)空间复杂度O(1)算法步骤将第一待排序序列第一个元素看做一个有序序列,把第二个元素到最后一个元素当成是未排序序列。从头到尾依次扫描未排序序列,将扫描到的每个元素插入有序序列的适当位置。(如果待插入的元素与有序序列中的某个元素相等,则将待插入元素插入到相等元素的后面。)动图演示/* 直接插入排序 */ void insertion_sort(int n) { for(int i = 1; i < n; i++) { int t = x[i]; int j; for (j = i; j > 0 && x[j-1] > t ; j--) { x[j] = x[j - 1]; } x[j] = t; } }希尔排序希尔排序,也称递减增量排序算法,是插入排序的一种更高效的改进版本。但希尔排序是非稳定排序算法。希尔排序是基于插入排序的以下两点性质而提出改进方法的:插入排序在对几乎已经排好序的数据操作时,效率高,即可以达到线性排序的效率;但插入排序一般来说是低效的,因为插入排序每次只能将数据移动一位;希尔排序的基本思想是:先将整个待排序的记录序列分割成为若干子序列分别进行直接插入排序,待整个序列中的记录“基本有序”时,再对全体记录进行依次直接插入排序。时间复杂度平均:O(n1.5) 最好:O(n) 最坏O(n2)空间复杂度O(1) 算法步骤选择一个增量序列 t1,t2,……,tk,其中 ti > tj, tk = 1;按增量序列个数 k,对序列进行 k 趟排序;每趟排序,根据对应的增量 ti,将待排序列分割成若干长度为 m 的子序列,分别对各子表进行直接插入排序。仅增量因子为 1 时,整个序列作为一个表来处理,表长度即为整个序列的长度。/* 希尔排序 */ void shell_sort(int n) { for (int inc = n/3; inc >= 1; inc /= 3 ) { for (int i = inc; i < n; i++) { int t = x[i]; int j; for (j = i; j >= inc && x[j - inc] > t ; j -= inc) { x[j] = x[j - inc]; } x[j] = t; } } }冒泡排序时间复杂度平均: O(n2) 最好: O(n) 最坏:O(n2)空间复杂度O(1)算法步骤比较相邻的元素。如果第一个比第二个大,就交换他们两个。对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。这步做完后,最后的元素会是最大的数。针对所有的元素重复以上的步骤,除了最后一个。持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。动图演示/* 冒泡排序 */ void bubble_sort(int n) { bool change = true; for (int i = n-1; i >= 1 && change; i--) { change = false; for (int j = 0; j < i; j++) { if(x[j] > x[j + 1]) { swap(x, j, j + 1); change = true; } } } }快速排序快速排序是由东尼·霍尔所发展的一种排序算法。在平均状况下,排序 n 个项目要 Ο(nlogn) 次比较。在最坏状况下则需要 Ο(n2) 次比较,但这种状况并不常见。事实上,快速排序通常明显比其他 Ο(nlogn) 算法更快,因为它的内部循环(inner loop)可以在大部分的架构上很有效率地被实现出来。快速排序使用分治法(Divide and conquer)策略来把一个串行(list)分为两个子串行(sub-lists)。快速排序又是一种分而治之思想在排序算法上的典型应用。本质上来看,快速排序应该算是在冒泡排序基础上的递归分治法。快速排序的名字起的是简单粗暴,因为一听到这个名字你就知道它存在的意义,就是快,而且效率高!它是处理大数据最快的排序算法之一了。虽然 Worst Case 的时间复杂度达到了 O(n²),但是人家就是优秀,在大多数情况下都比平均时间复杂度为 O(n logn) 的排序算法表现要更好,可是这是为什么呢,我也不知道。好在我的强迫症又犯了,查了 N 多资料终于在《算法艺术与信息学竞赛》上找到了满意的答案:快速排序的最坏运行情况是 O(n²),比如说顺序数列的快排。但它的平摊期望时间是 O(nlogn),且 O(nlogn) 记号中隐含的常数因子很小,比复杂度稳定等于 O(nlogn) 的归并排序要小很多。所以,对绝大多数顺序性较弱的随机数列而言,快速排序总是优于归并排序。时间复杂度平均: O(nlogn) 最好: O(nlogn) 最坏:O(n2)空间复杂度O(nlogn) 用于方法栈算法步骤从数列中挑出一个元素,称为 “基准”(pivot);重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区退出之后,该基准就处于数列的中间位置。这个称为分区(partition)操作;递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序;递归的最底部情形,是数列的大小是零或一,也就是永远都已经被排序好了。虽然一直递归下去,但是这个算法总会退出,因为在每次的迭代(iteration)中,它至少会把一个元素摆到它最后的位置去。动图演示/* 快速排序 */ void quick_sort(int l, int u) { if (l >= u) return; int m = l; for (int i = l+1; i<= u; i++) { if(x[i] < x[l]) swap(x, ++m, i); } swap(x, l, m); quick_sort(l, m-1); quick_sort(m+1, u); }hash算法hash构造方法直接寻址法:取关键字或关键字的某个线性函数值为散列地址。即H(key)=key或H(key) = a?key + b,其中a和b为常数(这种散列函数叫做自身函数)数字分析法:分析一组数据,比如一组员工的出生年月日,这时我们发现出生年月日的前几位数字大体相同,这样的话,出现冲突的几率就会很大,但是我们发现年月日的后几位表示月份和具体日期的数字差别很大,如果用后面的数字来构成散列地址,则冲突的几率会明显降低。因此数字分析法就是找出数字的规律,尽可能利用这些数据来构造冲突几率较低的散列地址。平方取中法:取关键字平方后的中间几位作为散列地址。折叠法:将关键字分割成位数相同的几部分,最后一部分位数可以不同,然后取这几部分的叠加和(去除进位)作为散列地址。随机数法:选择一随机函数,取关键字的随机值作为散列地址,通常用于关键字长度不同的场合。除留余数法:取关键字被某个不大于散列表表长m的数p除后所得的余数为散列地址。即 H(key) = key MOD p, p<=m。不仅可以对关键字直接取模,也可在折叠、平方取中等运算之后取模。对p的选择很重要,一般取素数或m,若p选的不好,容易产生同义词。hash冲突及解决冲突原因:与散列函数有关,一个好的散列函数的值应尽可能平均分布。与解决冲突的哈希冲突函数有关。与负载因子的大小。太大不一定就好,而且浪费空间严重,负载因子和散列函数是联动的。解决冲突的办法开放定址法:线性探查法、平方探查法、伪随机序列法、双哈希函数法。拉链法:把所有同义词,即hash值相同的记录,用单链表连接起来。常用的hash函数unsigned int RSHash(char* str, unsigned int len) { unsigned int b = 378551; unsigned int a = 63689; unsigned int hash = 0; unsigned int i = 0; for(i = 0; i < len; str++, i++) { hash = hash * a + (*str); a = a * b; } return hash; } /* End Of RS Hash Function */ unsigned int JSHash(char* str, unsigned int len) { unsigned int hash = 1315423911; unsigned int i = 0; for(i = 0; i < len; str++, i++) { hash ^= ((hash << 5) + (*str) + (hash >> 2)); } return hash; } /* End Of JS Hash Function */ unsigned int ELFHash(char* str, unsigned int len) { unsigned int hash = 0; unsigned int x = 0; unsigned int i = 0; for(i = 0; i < len; str++, i++) { hash = (hash << 4) + (*str); if((x = hash & 0xF0000000L) != 0) { hash ^= (x >> 24); } hash &= ~x; } return hash; } /* End Of ELF Hash Function */ unsigned int DJBHash(char* str, unsigned int len) { unsigned int hash = 5381; unsigned int i = 0; for(i = 0; i < len; str++, i++) { hash = ((hash << 5) + hash) + (*str); } return hash; } /* End Of DJB Hash Function */javascript数据类型字符串 数字 布尔 对象 数组 undefined nulljs只有一种数字类型undefined:当声明的变量没有初始化的话,那这个变量的值就是undefinednull表示尚未存在的对象。
2024年12月12日
11 阅读
0 评论
0 点赞
2023-09-20
wctype.h
wctype.hwctype.h 提供 ctype.h 里面函数的宽字符版本。宽字符类型判断函数下面函数判断宽字符的类型。iswalnum() 测试宽字符是否为字母数字iswalpha() 测试宽字符是否为字母iswblank() 测试这是否是一个宽空白字符iswcntrl() 测试这是否是一个宽控制字符。iswdigit() 测试这个宽字符是否是数字iswgraph() 测试宽字符是否是可打印的非空格字符iswlower() 测试宽字符是否为小写iswprint() 测试宽字符是否可打印iswpunct() 测试宽字符是否为标点符号iswspace() 测试宽字符是否为空格iswupper() 测试宽字符是否为大写iswxdigit() 测试宽字符是否为十六进制数字wctype(),iswctype()iswctype()是上一节各种宽字符类型判断函数的通用版本,必须与wctype()配合使用。int iswctype(wint_t wc, wctype_t desc);iswctype()接受两个参数,第一个参数是一个需要判断类型的宽字符,第二个参数是宽字符类型描述,来自wctype()的返回值。如果宽字符属于指定类型,iswctype()返回一个非零值,否则返回零。wctype()用来获取某个种类宽字符的类型描述。wctype_t wctype(const char* property);wctype()的参数是一个给定的字符串,可用的值如下:alnum、alpha、blank、cntrl、digit、graph、lower、print、punct、space、upper、xdigit。wctype()的返回值的类型为 wctype_t,通常是一个整数。如果参数是一个无效值,则返回0。if (iswctype(c, wctype("digit"))) // 相当于 if (iswdigit(c))上面示例用来判断宽字符c是否为数值,相当于iswdigit()。iswctype()的完整类型判断如下。iswctype(c, wctype("alnum")) // 相当于 iswalnum(c) iswctype(c, wctype("alpha")) // 相当于 iswalpha(c) iswctype(c, wctype("blank")) // 相当于 iswblank(c) iswctype(c, wctype("cntrl")) // 相当于 iswcntrl(c) iswctype(c, wctype("digit")) // 相当于 iswdigit(c) iswctype(c, wctype("graph")) // 相当于 iswgraph(c) iswctype(c, wctype("lower")) // 相当于 iswlower(c) iswctype(c, wctype("print")) // 相当于 iswprint(c) iswctype(c, wctype("punct")) // 相当于 iswpunct(c) iswctype(c, wctype("space")) // 相当于 iswspace(c) iswctype(c, wctype("upper")) // 相当于 iswupper(c) iswctype(c, wctype("xdigit")) // 相当于 iswxdigit(c)大小写转换函数wctype.h 提供以下宽字符大小写转换函数。towlower() 将大写宽字符转换为小写towupper() 将小写宽字符转换为大写towctrans() 宽字符大小写转换的通用函数wctrans() 大小写转换的辅助函数,配合 towctrans() 使用先看towlower()和towupper()的用法示例。towlower(L'B') // b towupper(L'e') // Etowctrans()和wctrans()的原型如下。wint_t towctrans(wint_t wc, wctrans_t desc); wctrans_t wctrans(const char* property);下面是它们的用法示例。towctrans(c, wctrans("toupper")) // 相当于 towupper(c) towctrans(c, wctrans("tolower")) // 相当于 towlower(c)
2023年09月20日
14 阅读
1 评论
0 点赞
2023-09-20
wchar.h
wchar.h宽字符使用两个或四个字节表示一个字符,导致 C 语言常规的字符处理函数都会失效。wchar.h 定义了许多宽字符专用的处理函数。类型别名和宏wchar.h 定义了一个类型别名 wint_t,表示宽字符对应整数值。wchar.h 还定义了一个宏 WEOF,表示文件结束字符 EOF 的宽字符版。btowc(),wctob()btowc()将单字节字符转换为宽字符,wctob()将宽字符转换为单字节字符。wint_t btowc(int c); int wctob(wint_t c);btowc()返回一个宽字符。如果参数是 EOF,或转换失败,则返回 WEOF。wctob()返回一个单字节字符。如果参数是 WEOF,或者参数宽字符无法对应单个的单字节字符,则返回 EOF。下面是用法示例。wint_t wc = btowc('B'); // 输出宽字符 B wprintf(L"Wide character: %lc\n", wc); unsigned char c = wctob(wc); // 输出单字节字符 B wprintf(L"Single-byte character: %c\n", c);fwide()fwide()用来设置一个字节流是宽字符流,还是多字节字符流。如果使用宽字符专用函数处理字节流,就会默认设置字节流为宽字符流,否则就需要使用fwide()显式设置。int fwide(FILE* stream, int mode);它接受两个参数,第一个参数是文件指针,第二个参数是字节流模式,有三种选择。0:字节流模式保持原样。-1(或其他负值):设为多字节字符流。1(或其他正值):设为宽字符流。fwide()的返回值也分成三种情况:如果是宽字符流,返回一个正值;如果是多字节字符流,返回一个负值;如果是普通字符流,返回0。一旦设置了字节流模式,就无法再更改。#include <stdio.h> #include <wchar.h> int main(void) { wprintf(L"Hello world!\n"); int mode = fwide(stdout, 0); wprintf(L"Stream is %ls-oriented\n", mode < 0 ? L"byte" : L"wide"); }上面示例中,wprintf()将字节流隐式设为宽字符模式,所以fwide(stdout, 0)的返回值大于零。宽字符专用函数下面这些函数基本都是 stdio.h 里面的字符处理函数的宽字符版本,必须使用这些函数来操作宽字符。fgetwc() 从宽字符流中获取宽字符,对应 fgetc()。fgetws() 从宽字符流中读取宽字符串,对应 fgets()。fputwc() 将宽字符写入宽字符流,对应 fputc()。fputws() 将宽字符串写入宽字符流,对应 fputs()。fwprintf() 格式化宽输出到宽字符流,对应 fprintf()。fwscanf() 来自宽字符流的格式化宽字符输入,对应 fscanf()。getwchar() 从 stdin 获取一个宽字符,对应 getchar()。getwc() 从 stdin 获取一个宽字符,对应 getc()。putwchar() 写一个宽字符到 stdout,对应 putchar()。putwc() 写一个宽字符到 stdout,对应 putc()。swprintf() 格式化宽输出到宽字符串,对应 sprintf()。swscanf() 来自宽字符串的格式化宽输入,对应 sscanf()。ungetwc() 将宽字符推回输入流,对应 ungetc()。vfwprintf() 可变参数的格式化宽字符输出到宽字符流,对应 vfprintf()。vfwscanf() 来自宽字符流的可变参数格式化宽字符输入,对应 vfscanf()。vswprintf() 可变参数的格式化宽字符输出到宽字符串,对应 vswprintf()。vswscanf() 来自宽字符串的可变参数格式化宽字符输入,对应 vsscanf()。vwprintf() 可变参数格式化宽字符输出,对应 vprintf()。vwscanf() 可变参数的格式化宽字符输入,对应 vscanf()。wcscat() 危险地连接宽字符串,对应 strcat()。wcschr() 在宽字符串中查找宽字符,对应 strchr()。wcscmp() 比较宽字符串,对应 strcmp()。wcscoll() 比较两个考虑语言环境的宽字符串,对应 strcoll()。wcscpy() 危险地复制宽字符串,对应 strcpy()。wcscspn() 不是从宽字符串前面开始计算字符,对应 strcspn()。wcsftime() 格式化的日期和时间输出,对应 strftime()。wcslen() 返回宽字符串的长度,对应 strlen()。wcsncat() 更安全地连接宽字符串,对应 strncat()。wcsncmp() 比较宽字符串,长度有限,对应 strncmp()。wcsncpy() 更安全地复制宽字符串,对应 strncpy()。wcspbrk() 在宽字符串中搜索一组宽字符中的一个,对应 strpbrk()。wcsrchr() 从末尾开始在宽字符串中查找宽字符,对应 strrchr()。wcsspn() 从宽字符串前面的集合中计算字符,对应 strspn()。wcsstr() 在另一个宽字符串中找到一个宽字符串,对应 strstr()。wcstod() 将宽字符串转换为 double,对应 strtod()。wcstof() 将宽字符串转换为 float,对应 strtof()。wcstok() 标记一个宽字符串,对应 strtok()。wcstold() 将宽字符串转换为 long double,对应 strtold()。wcstoll() 将宽字符串转换为 long long,对应 strtoll()。wcstol() 将宽字符串转换为 long,对应 strtol()。wcstoull() 将宽字符串转换为 unsigned long long,对应 strtoull()。wcstoul() 将宽字符串转换为 unsigned long,对应 strtoul()。wcsxfrm() 转换宽字符串以根据语言环境进行比较,对应 strxfrm()。wmemcmp() 比较内存中的宽字符,对应 memcmp()。wmemcpy() 复制宽字符内存,对应 memcpy()。wmemmove() 复制宽字符内存,可能重叠,对应 memmove()。wprintf() 格式化宽输出,对应 printf()。wscanf() 格式化宽输入,对应 scanf()。多字节字符专用函数wchar.h 也定义了一些多字节字符的专用函数。mbsinit() 判断 mbstate_t 是否处于初始转换状态。mbrlen() 给定转换状态时,计算多字节字符串的字节数,对应 mblen()。mbrtowc() 给定转换状态时,将多字节字符转换为宽字符,对应 mbtowc()。wctombr() 给定转换状态时,将宽字符转换为多字节字符,对应 wctomb()。mbsrtowcs() 给定转换状态时,将多字节字符串转换为宽字符串,对应 mbstowcs()。wcsrtombs() 给定转换状态时,将宽字符串转换为多字节字符串,对应 wcstombs()。
2023年09月20日
11 阅读
0 评论
0 点赞
1
...
4
5
6
...
35