c语言知识点问答整理

内容来自《程序设计基础实验教程》钟梅主编

看这本书觉得文章中问答部分编的挺受用,因此特意从书上抄写下来,供参考。

指针部分:

1.指针变量为什么要初始化?
如果没有初始化,它存放的地址是随机值。如果此地址正好是系统正在使用的内存地址,那么该操作就将改写系统正在使用的某个数据,可能导致系统被破坏。不确定初始的指针变量赋予空值NULL。

2.既然0表示空指针,那么空指针就是字节中各位都为0的地址,对吗?
不一定。每个C语言编译器都被允许许多不同的方式表示空指针,而且不是所有编译器都使用0地址。一些编译器空指针使用不存在的内存地址。硬件会检查出这种试图通过空指针访问内存的地址。当在指针环境中使用0时,编译器会把它转换为适当的内部形式。

3.NULL值为0,'\0'值也为0,可以用NULL表示空字符吗?
绝对不可以。NULL用于表示空指针。一些编译器会据此把NULL定义为(void *)0。这样,把指针类型的NULL用作空字符就违反了标准C的规则。

4.指向不同类型的指针占用的内存空间大小都相同吗?
是的。指针所占内存空间大小只随机器硬件不同而不同。在32位机器上,所有指针变量都占用4个字节的空间。

5.指针的值能否显示?
可以显示,调用printf函数,在格式串中采用%p,假设ptr已有明确的定义,printf("%p\n",(void*)prt).

6.地址信息使用%p和%x均可以打印输出,两者有何区别?
在内存单元的地址输入功能上,两者功能相同。%p按照8位域宽十六进制方式输出,保留了前导0的输出,而%x舍弃了前导0,也按照十六进制输出。总体上%p专用于地址输出,而%x也用于其他数据的输出,就地址功能输出功能而言,两者相同。

7.如何理解指针运算?
指针的运算种类有限,仅限于算术运算,关系运算和赋值预算。*p++等价于*(p++).

字符串:
1.gets()和scanf()在提取字符串数据输入的功能上,有什么区别?
gets允许提取用户输入带有空格的字符串信息 ,而scanf则提取用户输入的信息,遇到空格时结束。
2.是否每个字符数组都应该包含'\0'字符空间?
不是,因为不是每个字符数组都作为字符串使用。

结构体
1.结构体类型和结构体变量的区别?
结构体类型不分配空间,而用定义好的结构体类型声明的变量,需要为变量分配空间。
2.使用==来判断两个结构体变量是否相等为什么不合法?
这种操作超出了C语言的范围。逐个比较结构成员显得效率较低。比较结构中的全部字节看起来相对可行,但是,如果结构中含有空洞(即无用字节,会造成用sizeof计算的结构体大小和实际加起来的不等),则比较字节会产生不正确的结果。

链表
1.使用malloc分配空间时,参数为什么要写成sizeof(结构体类型)*n的形式?
因为多数编译器在进行内存分配时,会遵循内存对齐机制,可能会在结构中留有空洞,这会使得实际分配可能会超过程序设计实际需要,使用sizeof运算符来计算分配空间,将对齐等考虑因素留待编译器自动处理,程序更加规范。
2.动态分配的内存会被自动释放吗?
不会,必须手动用free释放。若不显示释放,则会造成该动态内存无法访问到,而因为没有及时返还给操作系统,操作系统也不能将它分配给其他需要的地方,这样就造成了内存浪费或者内存泄漏。如果这样的分配出现函数中,而函数又被频繁调用,那么泄漏的内存会越来越多,最后可能导致操作系统没有可以分配的内存,造成动态申请内存失败,以至于程序不能运行。一般地,所有泄漏的内存会在应用程序退出后,统一返还操作系统。
3.链表的头指针为NULL,这意味着什么?
不带有头节点的链表,头指针为NULL,意味着链表还没有任何节点,是个空链表。
4.若头插法创建链表时,忘记为头指针初始化为NULL,会有什么后果?
根据头插法创建链表的特点,第一个创建的结点会是链表的尾结点。可是由代码p->next=head,可知第一个建立的结点,其指针域得到头指针head的值,并非NULL,这样,会导致链表没有了尾结点标识。
5.如何区分带不带头结点的空链表?
不带头节点的链表,头指针为NULL,即若有头指针用head表示,则head=NULL;带有头节点的链表,头指针非空,头节点的指针域非空,即head->next=NULL。

文件:
1.当程序终止时,所有打开的不都是会自动关闭的吗?为什么一定要使用fclose函数关闭文件?
通常情况下,程序终止时,所有打开的文件会自动关闭。但如果调用abort函数终止程序就不会了。即使不用abort函数,调用fclose函数关闭文件好处是:第一,会减少打开文件的数量。操作系统对程序每次打开的文件数量有所限制,而大规模的程序可能好与此限制冲突。第二,程序易于阅读和修改。第三,更加安全。关闭文件可以确保正确更新文件的内容和目录。如果程序崩溃,文件也不会受到影响。
2.fgets与gets有什么区别?
gets把读到的回车符换成'\0'字符,不保留在输入缓冲区。fgets把回车符当做普通字符存储,并在末尾追加'\0'字符。
3.如何避免多次包含同一个头文件?
第一,头文件使用#ifndef _HEAD_H #define _HEAD_H ....#endif.第二,头文件开头使用#pragma once。
解决了头文件重复包含的问题(编译阶段的问题),但是不能解决重复定义的问题(链接期间的问题)。

猜你喜欢

转载自blog.csdn.net/u013516331/article/details/45893419
今日推荐