C语言问题记录

xiaoxiao2021-02-28  107

       最近在看两本书,一本是C缺陷和陷阱,这本书大概在本科期间,也有六七年了,现在在此读起,有种温故而知新的感觉;另一本是程序员的自我修养。读的时候,发现很多以前不是很明白的问题逐渐清晰起来。在此就这些问题和解释做一下记录。        1,.h文件和.c文件的区别? 虽然有的时候.h和.c都是成对的出现,但是他们之间并没有必须要求成对的出现。使用.h的出发点通常是,在某个函数被调用之前,使用include包含该函数声明的头文件,使得编译顺利的通过。这类的头文件可以是对外暴露接口的头文件,也可以是同一.c中为了顾及函数的调用顺序而增加的函数声明头文件。最重要的原因是,编译器是按照.c文件为基本单元进行编译的,头文件仅仅是在include时候进行展开,因此在include中也可以包含.txt的文件,只是按照约定,通常是.h文件。值的注意的是,头文件中通常表述的是变量的声明和函数的声明,因为如果使用定义的话,在被多个.c包含的时候会产生重定义错误。        2,声明和定义的区别?        这里分为两种情况,一种是变量的声明和定义;另一种是函数的声明和定义。函数的定义是包含函数体的情形,声明就是没有包含函数体的情形。没有函数体还包括使用了extern关键字和没有extern关键字的情况。使用extern的表示函数体在其它的.c或者静态库中进行了定义,没有使用的是最常见的情形。变量的声明就是使用extern关键字,没有是使用的则为变量的定义,在生成目标文件的时候为其分配存储空间(未初始话变量除外)。当然这里面的变量指的是全局变量,局部变量是在程序运行期间,由栈分配临时空间。        3,局部变量为什么要初始化?        全局未初始化的变量,默认值为0或空。而局部变量则不同,局部变量的空间是在栈上面进行分配的。而其栈空间的值则是不确定的,因此就会出现一个没有赋给初值的指针成为野指针的情况,所以对于指针,要赋值为NULL。        4,C语言函数的压栈顺序?        默认的压栈顺序是从由右向左进行的,这样对于像printf这种参数是不固定的有非常好的作用。因为像printf这种不定参的函数,第一个参数是可以确定参数的个数的。那么在压栈的时候,将第一个参数置于栈顶位置出,就比从左向右压栈容易确定参数的个数。        5,宏定义,内联函数?        宏定义通常用来定义一些魔术数字,但有的时候也可以定义函数,但是这种情况出错较多,如果所定义的函数只被调用一次还是可以使用的。内联函数虽然和宏一样也是在编译的时候将函数体展开,但是内联函数首先是一个函数,它会进行参数的检查等,相对宏来说隐藏的错误更少。由于内联函数会在编译的时候进行展开,因此目标文件维护的就是这个函数代码的多份拷贝,比之正常函数来说,代码更容易膨胀。因此只有在代码较为短小的情况下,建议使用内联函数。如果代码本身的开销要大于函数进出栈所带来的开销,而且被多次的调用,还是建议使用正常的函数。        6,f和f()的区别,f表示函数名。        f只是取函数的地址并不执行函数体,而f()是调用函数体内容。指针ptr仅仅代表变量地址,而*ptr才代表指针所指向的变量内容。当然ptr如果代表的是函数地址,这ptr()表示的是函数的执行,其是(*ptr)()的缩写形式。        本文为村中少年原创文章,转载记得加上小尾巴偶,博主链接这里。

村中少年 认证博客专家 网络安全 IDS/DPI 网络协议 网络安全工程师,计算机科学与技术本硕,多年从事IDS网络入侵检测,DPI深度报文检测等网络安全引擎方面经验,热爱技术,分享知识
转载请注明原文地址: https://www.6miu.com/read-50015.html

最新回复(0)