C基本常被初学者忽略的秘密

    xiaoxiao2026-06-08  0

    C语言基本各专题都总结过了,但是还有些基本概念,总是被忽略但还是挺重要的。 1.操作系统的一种理解: 1).操作系统负责管理和资源调度,而应用程序实际上来干活,他们间用API做接口。在裸机下没操作系统,所有资源都用来干活,干活量不大时肯定这样更快;但对更复杂的工作,有人管理,有人干活效率才更高。 2).单纯的API是很简陋的,没有服务程序;把他封装起来就变成了C库函数,这样更好用。比如把open封装为fopen,就添加了缓冲机制。 2.main函数的参数与返回值 参数: 0).需要注意的一点是main函数是程序入口,他的参数是void或者(int argc,char *argv[],后面一个写成cha**argv也行),返回值是int类型(void虽然能用,但是是错误的) 1).参数:传递一个字符串数组(和字符数组区分开),argc为字符串个数,argv[n]为第n+1(re0)个字符串; 注意: 使用时注意用argc检测参数个数; 默认argc为1,是他的用于执行该程序的那个语句;多个参数在执行语句后空格隔开,注意参数都是字符串。 2).父进程fork一个子进程,然后字进程和一个程序绑定起来去执行(exec函数族),我们在exec的时候可以给他同时传参。 返回值: 1).返回值是int类型。当main函数返回时,就表示程序的结束。返回值是0表示正常结束,为-1表示错误结束。 2)返回值给了执行该程序的进程的父进程。可用shell 脚本的$?查看。 #include<stdio.h> int main(int argc,char **argv) { int result=0,i; if(argc>1) { for(i=1;i<argc;i++) result+=atoi(argv[i]); printf("the result is %d\n",result); } else printf("请输入参数\n"); return 0; } 3.void类型 1).类型意味着:该变量在内存中占得空间大小。   在内存中存储的01序列的解析方式。(写的方式,读的方式)。 2).void类型:不明确的类型,可以被强制类型转换成别的类型. 3).一般用void *类型,来指向一段内存空间,意味着这段内存的中内容的解析方式不确定。比如int *p=(int *)malloc(sizeof(int)); 用void定义普通变量一般没意义, 也可能不会通过. 4.NULL 1).NULL不是C语言关键字,本质上是一个宏定义,NULL的标准定义: #ifdef _cplusplus // 条件编译 #define NULL 0 #else #define NULL (void *)0 // 这里对应C语言的情况 #endif 2).NULL是一个void*指针,指向地址为0的内存空间;常用来初始化使用以避免野指针,解引用野指针是很危险的 5.运算中的临时匿名变量 1).强制类型转换 float a=12.34; int b; b=(int)a; printf("a=%f,b=%d\n",a,b);a=12.34,b=12.其实里面有一个隐蔽的第三方,在a给b赋值之间保存12. 2).不同类型间数据运算 int a=10,b=3; float c=a/b;       //c=3.00000 6.调试与DEBUG宏 1).程序调试的常见方案:单步调试、裸机LED调试、打印信息、log文件: 利用调试器进行单步调试(譬如IDE中,Jlink)适用于新手,最大的好处就是直观,能够帮助找到问题。缺点是限制性大、速度慢。 裸机使用LED、蜂鸣器等硬件调试,适合单片机裸机程序 printf函数打印调试,比较常用,作为程序员必须学会使用打印信息调试。好处是具有普遍性,几乎在所有的情况下都能用。 log文件(日志文件)是系统运行过程中在特定时候会打印一些调试信息,日志文件记录下来这些调试信息以供后续查找追查问题。适合于系统级或者大型程序的调试。 2). DEBUG版本就是包含了调试信息输出的版本,在程序测试过程中会发布debug版本,这种版本的程序运行时会打印出来调试信息/log文件,这些信息可以辅助测试人员判断程序的问题所在。DEBUG版本的坏处是输出调试信息占用了系统资源,拖慢了系统运行速度。因此DEBUG版本的性能低于RELEASE版本。 RELEASE版本就是最终的发布版本,相较于DEBUG版本的功能代码是一样的,但是去掉了所有的调试信息。适合最终测试通过要发布的程序,因为去掉了调试信息所以程序的运行效率要更高。 DEBUG和RELASE版本其实是一套源代码。源代码中是有很多的打印调试信息的语句的,如何来控制生成DEBUG和RELEEASE版本?靠条件编译,靠一个宏。 DEBUG宏大概的原理是: #ifdef DEBUG #define dbg() printf() #else #define dbg() #endif 应用程序中DEBUG宏 #ifdef DEBUG #define DBG(...) fprintf(stderr, " DBG(%s, %s(), %d): ", __FILE__, __FUNCTION__, __LINE__); fprintf(stderr, __VA_ARGS__) #else #define DBG(...) #endif 注:__FILE__等是C语言中的预定义宏,就是说这个东西是个宏定义,但是是C语言自己定义的。这些宏具有特殊的含义,譬如__FILE__表示当前正在编译的c文件的文件名。 7.C变参函数: 实质上是通过宏,根据堆栈各个压栈,获取各个参数的地址。 、、。。未完待续 接下来还有链表,还变参函数的实践,字符串处理函数的实践未完成。。还是先搞裸机吧,也是挺累的,颓废了两天,明天搞起。
    转载请注明原文地址: https://ju.6miu.com/read-1310311.html
    最新回复(0)