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

来源:互联网 发布:php代练工作室网站源码 编辑:程序博客网 时间:2024/06/06 10:01


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);}elseprintf("请输入参数\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变参函数:
实质上是通过宏,根据堆栈各个压栈,获取各个参数的地址。

、、。。未完待续


接下来还有链表,还变参函数的实践,字符串处理函数的实践未完成。。还是先搞裸机吧,也是挺累的,颓废了两天,明天搞起。
0 0
原创粉丝点击