二刷C语言后,一万字整理细碎知识点

基础知识篇

ASCII码

主要以下几点记住比较好

  • A-Z 65-90
  • a-z 97-122
  • 对应的大小写字母差值32
  • "\n"对应的ASCII是10
  • 0-31这些特殊字符不可以在标准输出上打印

sizeof表达式

用法
  1. sizeof (类型)
  2. sizeof 表达式(表达式可以不加括号)
返回结果size_t

size_t返回的是对象所占内存大小,单位是字节,不过size_t在表示的可能的是unsigned int,也可能是unsigned long,unsigned long long,具体取决于平台,这也增加了代码的可移植性,因为size_t总代表当前平台size_t返回类型

sizeof返回的表达式不计算
inta=1,b=2;printf("%d",sizeof(b=a+1));//4,int的大小printf("%d",b);//2,上面的运算不进行

原因是在编译时就完成处理了,表达式的运算要在运行期间进行,所以自然就不计算了

signed 和 unsigned

是否有符号,用第一位二进制位表示正负,因此无符号在正数范围内表示范围大了一倍

值得注意的是,int 等价于signed int,但是chat 不等价与signed char,具体有环境确定

printf

左对齐与右对齐

printf默认右对齐,前面用空格填充,如果想要左对齐,使用‘-’

printf("%-5d",2);
最小宽度和小数位数的参数传入
printf("%*.*d",5,2,2);//输出结果 2.00
输出部分字符串
printf("%.5s\n","hello world");//输出结果 hello
参数个数问题

printf中占位符的个数与参数个数一一对应,有n个占位符,printf就有(n + 1)个参数,因为
前面制定的format也是参数

返回值
intprintf(constchar*format,...);

返回的是屏幕上打印字符的个数,比如以下程序,输出的结果是4321

printf("%d",printf("%d",printf("%d",43)));

scanf

使用方式

对于想要存入的变量,比如int char float…这些需要传址调用,而对于指针类变量,比如字符串,就不需要,因为他本身可以看作指向字符串第一个字符的指针

读取模式

用户进行输入时,会将输入内容存入缓冲区,当用户按下回车时,开始根据占位符进行解读,直到解读完毕或者出现错误

同时,scanf会自动过滤空白字符,比如换行符、制表符、回车符等等,直接从其他字符读取

//input: -13.45e12#0inta;floatb;scanf("%d",&a);printf("%d\n",a);//-13scanf("%f",&b);printf("%d\n",b);// .45e12
返回值

scanf返回成功读取到的数据的个数,全部匹配失败返回0,读取错误或者读取到文件结尾返回EOF(end of file)

%c 和 %s

这是两个比较特殊的

  • %c 不忽略空白字符,接受读取到的第一个字符,如果要强制忽略的话,采取
chara;scanf(" %c",&a);
  • %s 读取字符串时,遇到空白字符就停止,想要读取句子,就要多个%s一起使用,同时,%s
    在存储时,会在字符串末尾加上’\0’;
赋值忽略符
scanf("%d/%d/%d",&str);scanf("%d-%d-%d",&str);scanf("%d%*c%d%*c%d",&str);

这样,前两句能读取得第三句都可以读取,因为%*c表示这里读取的字符不存储

if else语句的悬空else问题:

inta=0,b=1;if(a==1)// (1)if(b==1)//(2)printf("a");elseprintf("b");

这里else语句就是悬空的else,他会与最近的if匹配,即(2)

因此上面的语句不会输出任何内容

switch语句

  • 没有break就一直往下执行
  • 只有整形表达式可以做switch的判断依据
  • default和case的位置关系没有规定,只不过一般推荐default写在最后

rand与srand

  • rand是C语言中常用的随机数产生算法,但这是伪随机,对传入的数字(“种子”)进行一系列确定的运算后得到一个“随机数”
  • 因此,只要给定的种子是随机的,产生的数字也就是随机的,常用的种子有time和设备随机数(cpp)
  • time传入null时,返回当前时间与1970年1月1日0时0分0秒的差值,以秒为单位,返回结果的类型是time_t,是32位或者64位的随机数。

作用域和生命周期的概念

  • 作用域
    程序中的变量并不是一直有效,限定这个变量有效的代码区间,就是这个变量的作用域
  • 生命周期
    从申请内存到内存回收的时间区间就是一个变量的生命周期

static修饰

static修饰变量表示该变量为静态变量,存储在内存的静态区,生命周期与程序相同

static修饰,无论是变量还是函数,都只在本文件中有效,extern关键字也无法改变这一属性

函数栈帧与栈溢出

函数被调用时,需要在内存的栈区开辟一块空间来存放调用过程中局部变量,只要不返回空间就不释放,这就是函数栈帧;而如果栈空间被打满了,比如函数递归调用过深,就会出现栈溢出(stack overflow),导致程序被操作系统杀死

源码、反码、补码

对于正数来说三者相同,对于负数来说三者不同

源码按位取反后得到反码,反码+1后得到补码,在内存中存放的也是补码

原因:cpu只有加法器,没有加法器,通过补码就可以使用“加法”处理减法,避免额外的电路设计

逻辑右移和算术右移

逻辑右移符号位补0,算术右移补原符号位;

整形提升

对于char,short这些长度比int(4)小的类型来说,参与运算时,因为cpu中整形运算器一般处理长度为4,并且这也是寄存器的处理长度,所以这些类型会被提升为int的长度
提升方式:对于有符号的类型,用原符号位补全,对于无符号的类型,使用0来进行补全

变长数组的“变长”

变长数组的“变长”之的并不是长度的可变性,指的是数组的大小有变量或者是表达式所确定,因此他的大小是在运行时确定的,而且确定后不会发生改变

函数的定义与声明的关系

  • 所谓定义就是写出来这个函数需要进行怎样的操作,而声明就是告诉编译器有怎么样的一个函数
  • 如果函数的定义写在使用之前,就不需要声明;否则,需要先声明后使用,否则连接报错
intadd(intx,inty);//定义在使用之后,先声明后使用intmain(){inta=add(1,2);return0;}intadd(intx,inty){returnx+y;}

const 修饰指针变量

一句话概括:const 在 * 左边,指针指向的变量不可修改;const 在 * 右边,指针变量
本身不可修改

关于数组名的理解

数组名代表了数组首元素的地址,但是在sizeof和&上有区别

intarr[10]={0};printf("%p",sizeof(arr));printf("%p",&arr);printf("%p",&arr+1);printf("%p",&arr[0]);

&加上数组名,取出的是整个数组的地址,因此进行指针+常数的运算时,跳过的是整个数组的地址

而sizeof(数组名),计算的是整个数组的大小

[]下表引用操作符,可以理解为先移动,在解引用,例如arr[5]可以理解为*(arr + 5);

用二级指针模拟二维数组

所谓二级指针,其实就是指向指针的指针,而无论二维数组,还是以为数组,在内存中存放时,
其空间上都是连续的

intarr1={1,2,3};intarr2={4,5,6};intarr3={7,8,9};intarr4={arr1,arr2,arr3};

这里形成的arr4就是模拟的二维数组,只不过arr4每一行在空间上连续,但是行与行之间大概率是
分散的,而真正的二维数组无论行内还是行间都是连续的

二维指针数组的传参,这里可以引入指针数组的概念,即指向一个数组的指针

int(*parr)[10];//这就是一个数组指针,指向一个大小为10的数组voidfunction(intarr[2][3]);//这就是一个二维数组的传参,接受一个两行三列的指针数组voidfunction1(int(*arr)[3]);//这也是二维数组的传参方式,指向一个(首个)数组(二维数组的行)

字符指针变量

charstr1[]="hello world";charstr2[]="hello world";constchar*str3="hello world";constchar*str4="hello world";if(str1==str2)printf("1");if(str3==str4)printf("2");

以上程序只会输出2,原因是c和cpp会把常量字符串存放在单独的内存区域,所以str3和str4两个
指针会指向同一块内存;但是如果用常量字符串去初始化字符数组的话,就会单独初始化一块新的内存空间,所以str1和str2代表了不同的数组首元素地址

指针大练兵:手撕qsort

参考代码如下:

intcmp_func(void*p1,void*p2){return(*(int*)p1-*(int*)p2);}voidswap(void*p1,void*p2,intsz){for(inti=0;i<sz;i++){chartmp=*((char*)p1+i);*((char*)p1+i)=*((char*)p2+i);*((char*)p2+i)=tmp;}}voidmy_qsort(void*base,intcount,intsz,int(*cmp_func)(void*,void*)){for(inti=0;i<count-1;i++){for(intj=0;j<count-i-1;j++){if(cmp_func((char*)base+j*sz,(char*)base+(j+1)*sz)>0){swap((char*)base+j*sz,(char*)base+(j+1)*sz,sz);}}}}

面试中常考的手撕函数

strlen

这个是最经典的之一,《高质量的C/C++编成指南》中林锐老师就提过自己关于strlen函数在面试时的手撕经历。。。

intstrlen(char*str){if(str==NULL){return0;}char*begin=str;while(*str!='\0'){str++;}returnstr-begin;}

strcpy

char*strcpy(constchar*src,char*des){assert(src!=nullptr&&des!=nullptr);char*ret=des;while((*des++=*src++));returnret;}

strcat

char*strcat(char*des,constchar*src){assert(des!=NULL&&src!=NULL);char*ret=des;while(*des){des++;}while((*des++=*src++));returnret;}

strcmp

intstrcmp(constchar*str1,constchar*str2){assert(str1!=NULL&&str2!=NULL);while(*str1==*str2){if(*str1=='\0')return0;str1++;str2++;}return*str1-*str2;}

strstr

char*strstr(constchar*str1,constchar*str2){char*cp=(char*)str1;char*s1,*s2;if(!*str2){returnNULL;}while(*cp){s1=cp;s2=(char*)str2;while(*s1&&*s2&&*s1==*s2){s1++;s2++;}cp++;}returnNULL;}

strtok

char*strtok(char*str,constchar*sep);//使用方式:例如下面获取ip信息的过程intmain(){charip[]="172.17.0.1";for(str=strtok(ip,".");str!=NULL;str=strtok(NULL,".")){printf("%s",str);}return0;}

memcpy 和 memmove

这两个很相像,但是前者对于重合内存的处理是未定义行为,后者可以处理重叠内存

memcpy模拟实现

void*memcpy(void*des,constvoid*src,intnum){void*ret=des;while(num--){*((char*)des)=*((char*)src);des=(char*)des+1;src=(char*)src+1;}returnret;}

memmove的模拟实现

void*memmove(void*des,constvoid*src,intnum){void*ret=des;if(des<=src||(char*)des>=(char*)src+num){while(num--){*((char*)des)=*((char*)src);des=(char*)des+1;src=(char*)src+1;}}else{des=(char*)des+num-1;src=(char*)src+num-1;while(num--){*((char*)des)=*((char*)src);des=(char*)des-1;src=(char*)src-1;}}returnret;}

另外还有两个函数memset 和 memcmp

void*memset(void*des,intvalue,intnum);intmemcmp(constvoid*p1,constvoid*p2,intnum);

结构体相关

位段

不跨平台

这是位段的性质,需要注意

写法
structA{char_a:1;char_b:5;int_c:2;}
大小

位段空间的开辟以四个字节或者一个字节为单位

地址问题

因为位段实现的效果就是几个变量公用一个字节存储,所以会有一些变量的存储位置不是字节的起始位置,因此不能通过取地址的方式进行赋值(比如scanf)

可以采用的方式:

intnum_a=1;A a;a._a=num_a;

联合体

Union,与结构体的区别是各个成员变量公用统一块空间,因此可以通过联合体来判断当前机器的大小端字节序

之的注意的是,联合体也遵循结构体的的内存对齐原则

Union A{chara;intb;};/*01 00 00 00*/intmain(){Union A a;a.b=1;if(a.a==1)printf("小端");}

内存分配

  • 内核空间:这个区域用户代码无权修改
  • 栈区:在内核空间之上,主要存储局部变量,向下增长
  • 内存映射段:文件映射、动态库等,向栈区和堆区伸展
  • 堆区:动态内存,向上增长
  • 数据段:主要存储全局变量和静态变量
  • 代码段:主要存放只读常量(比如字符串)和二进制代码

柔性数组

C99之后支持的,在结构体各个成员变量的最后,允许一个大小不固定的数组的存在,可以通过动态内存的方式来改变其大小

输入输出函数

stdin和stdout

printf和scanf,最常用,不必多说

文件相关

文件打开关闭函数

fopen用于打开文件,返回一个FILE* 类型的文件指针,用于对文件的读写操作,具有两个参数,一个是文件名,另一个是打开方式,常见的打开方式有,其实就是 排列组合的方式。。。

对于打开失败的文件,返回NULL

打开方式意义打开方式意义打开方式意义
w只写w+读+写wb二进制写
r只读r+读+写rb二进制读
a追加a+读+追加ab二进制追加

对于关闭,使用fclose(FILE*);

写入函数
  • fputc 和 fputs,用于文件的写入,使用方法为写入内容+文件指针,两者主要区别是前者是char,后者是char*
  • fwrite,用于文件的二进制写入,需要传入写入内容,写入单元大小,写入单元数目,以及文件指针
  • fprintf,针对所有输出流,使用方法类似于printf,不过需要先传入文件指针或者输出目标
读取函数
  • fgetc 和 fputc,两者依旧是字符和字符串的区别,传入文件指针,用buffer来接收返回值
  • fread,二进制读取,第一个参数是buffer,其他与fwrite相同
  • fscanf,格式化输入,针对所有输入流,类似于scanf,也需要先知名目标输入流
随机读写函数

其实就是定位文件指针的位置

  • fseek,指明文件指针的便宜量,需要传入文件指针、偏移量、选项
  • ftell,获取文件指针位置,传入文件指针即可,返回size_t
  • rewind,将文件指针回其起始位置
读写情况判断

判断文件读取是否因为读到了EOF结束,采用feof(),而是否读写出错需要通过ferror

字符串操作函数

主要是两个格式化输入输出字符串函数: sprintf, sscanf,使用方法也基本与printf和scanf一样,只不过加上输入输出对象

函数示例
#defineSIZE5intmain(){FILE*pf=fopen("log.txt","w+");if(pf==NULL){return1;}fputs("hello world",pf);fseek(pf,5,SEEK_SET);fputs("hello world",pf);fseek(pf,0,SEEK_END);intpos=ftell(pf);printf("ths size of the file currently is %d",pos);rewind(pf);inta;while((a=fgetc(pf))!=EOF){putchar(a);}if(ferror(pf)){printf("I/O fail\n");}elseif(feof(pf)){printf("read successfully\n");}charfirst_word[50];fscanf(pf,"%s",first_word);printf("the first word is %s\n",first_word);fclose(pf);pf=fopen("arr.txt","wb+");if(pf==NULL){return1;}doublenums={1.,2.,3.,4.,5.};fwrite(nums,sizeof(*num),SIZE,pf);doublebuffer[SIZE];intread_num=fread(buffer,sizeof(*buffer),SIZE,pf);if(read_num!=SIZE){charerrmsg[50];sprintf(errmsg,"the errmsg is %s","文件字符读取数目出错");printf("%s",errmsg);}for(inti=0;i<SIZE;i++){printf("%d ",buffer[i]);}return0;}

末尾‘;’问题

最好不要加,有可能会导致在预处理阶段展开错误

#

可以将宏的一个参数替换为字面量,比如想实现一个宏完成对变量的值的打印

#definePRINT(n)printf("the val of "#n" is %d",n)

##

起到一个粘合剂的作用,把两边“粘”到一起

#defineMAX_FUNC(type)type type##_func(type a,type b){returna>b?a:b;}MAC_FUNC(int)

这样就完成了定义一个函数int_func,返回两个整形的较大者

做题提醒

因为宏其实就是在预处理时完成文本替换,所以一定要注意操作符的优先级与结合性

/* 比如下面的宏,预处理后是4 * A + B,而不是4 * (A + B) */#defineMAXA+Bchar*buffer=(char*)malloc(sizeof(int)*MAX);

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/1202253.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

解锁视频转文字新体验:5步实现学习资料数字化高效提取

解锁视频转文字新体验&#xff1a;5步实现学习资料数字化高效提取 【免费下载链接】bili2text Bilibili视频转文字&#xff0c;一步到位&#xff0c;输入链接即可使用 项目地址: https://gitcode.com/gh_mirrors/bi/bili2text 在信息爆炸的时代&#xff0c;视频已成为知…

信息访问优化方案:技术原理与实践指南

信息访问优化方案&#xff1a;技术原理与实践指南 【免费下载链接】bypass-paywalls-chrome-clean 项目地址: https://gitcode.com/GitHub_Trending/by/bypass-paywalls-chrome-clean 在数字信息时代&#xff0c;优质内容的获取常常受到访问控制机制的限制。本文将从技…

Blender MMD Tools在Blender 4.1中遇到的兼容性问题及解决方案探讨

Blender MMD Tools在Blender 4.1中遇到的兼容性问题及解决方案探讨 【免费下载链接】blender_mmd_tools MMD Tools is a blender addon for importing/exporting Models and Motions of MikuMikuDance. 项目地址: https://gitcode.com/gh_mirrors/bl/blender_mmd_tools …

NCMDump解锁音乐自由:突破网易云音乐NCM格式限制的无损转换指南

NCMDump解锁音乐自由&#xff1a;突破网易云音乐NCM格式限制的无损转换指南 【免费下载链接】ncmdump 项目地址: https://gitcode.com/gh_mirrors/ncmd/ncmdump NCMDump是一款专业的网易云音乐NCM格式转换工具&#xff0c;能够帮助用户解决下载的加密音频无法跨设备播放…

nohz和hotplug里与tick_sched相关的逻辑细节梳理

一、背景 在之前的博客 /proc/stat里的idle及iowait统计项的波动问题 里,我们讲到了一个cpu热插拔后,cpu的统计值会出现非预期的跳变,甚至数值会大幅度减少,这导致了做系统监控时的诸多不便。在之前的博客 /proc/stat里的idle及iowait统计项的波动问题 里的 2.6 一节及其他…

XUnity.AutoTranslator技术解析与应用指南

XUnity.AutoTranslator技术解析与应用指南 【免费下载链接】XUnity.AutoTranslator 项目地址: https://gitcode.com/gh_mirrors/xu/XUnity.AutoTranslator 1. 技术概述 XUnity.AutoTranslator是一款针对Unity引擎开发的实时文本翻译工具&#xff0c;通过拦截游戏渲染流…

开源大模型运维指南:Qwen3-4B-Instruct监控与告警部署实战

开源大模型运维指南&#xff1a;Qwen3-4B-Instruct监控与告警部署实战 1. 为什么需要监控一个“已经跑起来”的大模型&#xff1f; 你可能已经成功把 Qwen3-4B-Instruct-2507 部署在一台 4090D 显卡的机器上&#xff0c;网页推理界面打开顺畅&#xff0c;输入“写一封感谢邮件…

Windows右键管理:告别臃肿菜单,打造高效操作体验

Windows右键管理&#xff1a;告别臃肿菜单&#xff0c;打造高效操作体验 【免费下载链接】ContextMenuManager &#x1f5b1;️ 纯粹的Windows右键菜单管理程序 项目地址: https://gitcode.com/gh_mirrors/co/ContextMenuManager 你是否也曾在Windows系统中遭遇右键菜单…

Speech Seaco Paraformer企业定制化可能:热词库预加载实施方案

Speech Seaco Paraformer企业定制化可能&#xff1a;热词库预加载实施方案 1. 引言&#xff1a;为什么企业需要定制化语音识别&#xff1f; 在实际业务场景中&#xff0c;通用的语音识别模型往往难以满足特定行业或企业的专业需求。比如医疗、法律、金融等领域存在大量术语、…

Qwen3-Embedding-4B灰度发布:A/B测试部署流程

Qwen3-Embedding-4B灰度发布&#xff1a;A/B测试部署流程 Qwen3-Embedding-4B是通义千问系列最新推出的文本嵌入模型&#xff0c;专为高精度语义理解与多场景检索任务设计。该模型在保持高效推理能力的同时&#xff0c;显著提升了在复杂语义匹配、跨语言检索和长文本处理方面的…

Python自动化工具:从生活痛点到技术解决方案的实践指南

Python自动化工具&#xff1a;从生活痛点到技术解决方案的实践指南 【免费下载链接】auto_commemorative_coin_booking 项目地址: https://gitcode.com/gh_mirrors/au/auto_commemorative_coin_booking 一、痛点诊断&#xff1a;那些被重复劳动消耗的生活场景 在数字化…

2024效率工具零门槛指南:GitHub中文界面本地化全方案

2024效率工具零门槛指南&#xff1a;GitHub中文界面本地化全方案 【免费下载链接】github-chinese GitHub 汉化插件&#xff0c;GitHub 中文化界面。 (GitHub Translation To Chinese) 项目地址: https://gitcode.com/gh_mirrors/gi/github-chinese 作为开发者日常高频使…

显卡性能未达标?解锁隐藏设置的3个关键策略

显卡性能未达标&#xff1f;解锁隐藏设置的3个关键策略 【免费下载链接】nvidiaProfileInspector 项目地址: https://gitcode.com/gh_mirrors/nv/nvidiaProfileInspector 当你发现高端NVIDIA显卡在游戏中未能发挥全部潜力时&#xff0c;是否考虑过驱动程序中那些被隐藏…

Qwen1.5-0.5B应用场景:智能客服情感识别案例

Qwen1.5-0.5B应用场景&#xff1a;智能客服情感识别案例 1. 智能客服的新思路&#xff1a;用一个模型搞定情感识别与对话 你有没有遇到过这样的情况&#xff1f;客服机器人明明听懂了你说的话&#xff0c;却冷冰冰地回应&#xff0c;完全get不到你的情绪。生气时得不到安抚&a…

右键菜单太乱?Windows右键菜单定制工具让操作效率提升300%

右键菜单太乱&#xff1f;Windows右键菜单定制工具让操作效率提升300% 【免费下载链接】ContextMenuManager &#x1f5b1;️ 纯粹的Windows右键菜单管理程序 项目地址: https://gitcode.com/gh_mirrors/co/ContextMenuManager Windows右键菜单定制工具是一款专为解决系…

提取码总丢失?试试这款工具,让资源获取效率提升10倍

提取码总丢失&#xff1f;试试这款工具&#xff0c;让资源获取效率提升10倍 【免费下载链接】baidupankey 项目地址: https://gitcode.com/gh_mirrors/ba/baidupankey 你是否也曾遇到这样的情况&#xff1a;朋友发来一个百度网盘链接&#xff0c;却怎么也找不到提取码&…

G-Helper显示异常修复:配置文件恢复与显示效果优化指南

G-Helper显示异常修复&#xff1a;配置文件恢复与显示效果优化指南 【免费下载链接】g-helper Lightweight Armoury Crate alternative for Asus laptops. Control tool for ROG Zephyrus G14, G15, G16, M16, Flow X13, Flow X16, TUF, Strix, Scar and other models 项目地…

百度网盘解析工具应用指南:突破下载速度限制的本地解决方案

百度网盘解析工具应用指南&#xff1a;突破下载速度限制的本地解决方案 【免费下载链接】baidu-wangpan-parse 获取百度网盘分享文件的下载地址 项目地址: https://gitcode.com/gh_mirrors/ba/baidu-wangpan-parse 您是否正在寻找一种无需付费会员即可提升百度网盘下载速…

如何用LeaguePrank打造专属英雄联盟社交形象?技术赋能下的个性化方案

如何用LeaguePrank打造专属英雄联盟社交形象&#xff1f;技术赋能下的个性化方案 【免费下载链接】LeaguePrank 项目地址: https://gitcode.com/gh_mirrors/le/LeaguePrank 开篇&#xff1a;每位玩家都在面对的三大痛点 你是否也曾遇到这样的困境&#xff1a;明明只想…

游戏实时翻译解决方案:零基础上手XUnity自动翻译器

游戏实时翻译解决方案&#xff1a;零基础上手XUnity自动翻译器 【免费下载链接】XUnity.AutoTranslator 项目地址: https://gitcode.com/gh_mirrors/xu/XUnity.AutoTranslator 当你打开一款期待已久的国外游戏&#xff0c;却被满屏陌生文字阻挡了探索乐趣时&#xff0c…