C语言期末考试内容(2)选择填空答案整理(基础章节内容附解析)

C语言期末考试内容(2)选择填空答案整理(基础章节内容附解析)


作业1: C程序设计概述

  • C语言程序执行时的顺序,入口是main函数

    main函数可以调用其他函数,但其他函数不能调用main函数,C程序的执行总是从main函数开始,最后回到main函数结束,C程序中main函数可以在任何位置出现,
    使用头文件的好处是为了避免重复定义(头文件被修改之后所有包含此文件的源文件都需要重新编译)
    从C编译器角度看,.h和.c皆是浮云,就是改名为.txt、.doc也没有大的分别。换句话说,就是.h和.c没啥必然联系。.h中一般放的是同名.c文件中定义的变量、数组、函数的声明,需要让.c外部使用的声明。这个声明有啥用?只是让需要用这些声明的地方方便引用。因为 #include “xx.h” 这个宏其实际意思就是把当前这一行删掉,把 xx.h 中的内容原封不动的插入在当前行的位置。由于想写这些函数声明的地方非常多(每一个调用 xx.c 中函数的地方,都要在使用前声明一下子),所以用 #include “xx.h” 这个宏就简化了许多行代码——让预处理器自己替换好了。也就是说,xx.h 其实只是让需要写 xx.c 中函数声明的地方调用(可以少写几行字),至于 include 这个 .h 文件是谁,是 .h 还是 .c,还是与这个 .h 同名的 .c,都没有任何必然关系。
    一个c文件里面必须有main函数吗?

    make files

    当然不一定啊,但是没有main函数不能编译成可执行程序,只能编译成中间文件(一些二进制文件)。这些中间文件也是有用的,比方说一个项目中有多个C文件时,每个可执行程序的源码中只会有一个main函数。将功能模块化可以减少重复编译,提高工作效率。另外中间文件还可以用来编译成静态或动态链接库等。

    头文件好像也没有main函数吧

    编译是把代码转成机器代码;检查的是基本语法;链接则是要把所有机器码组成一个完整的逻辑程序,可能包含链接的各种库或头文件。除了全局静态的内容,入口肯定是main函数,没有main函数自然是不能链接成功的。

  • 在编译过程将要开始的时候,main.cpp 的内容已经发生了改变

#include 的作用是把它后面所写的那个文件的内容,完完整整地、一字不改地包含到当前的文件中来。值得一提的是,它本身是没有其它任何作用与副功能的,它的作用就是把每一个它出现的地方,替换成它后面所写的那个文件的内容。简单的文本替换,别无其他。因此,main.cpp 文件中的第一句(#include"math.h"),在编译之前就会被替换成 math.h 文件的内容。即在编译过程将要开始的时候,main.cpp 的内容已经发生了改变
头文件的作用就是被其他的 .cpp 包含进去的。它们本身并不参与编译,但实际上,它们的内容却在多个 .cpp 文件中得到了编译。通过"定义只能有一次"的规则,我们很容易可以得出,头文件中应该只放变量和函数的声明,而不能放它们的定义。因为一个头文件的内容实际上是会被引入到多个不同的 .cpp 文件中的,并且它们都会被编译。放声明当然没事,如果放了定义,那么也就相当于在多个文件中出现了对于一个符号(变量或函数)的定义,纵然这些定义都是相同的,但对于编译器来说,这样做不合法。
应该记住的一点就是,.h头文件中,只能存在变量或者函数的声明,而不要放定义。即,只能在头文件中写形如:extern int a; 和 void f(); 的句子。这些才是声明。如果写上 inta;或者 void f() {} 这样的句子,那么一旦这个头文件被两个或两个以上的 .cpp 文件包含的话,编译器会立马报错。(关于 extern,前面有讨论过,这里不再讨论定义跟声明的区别了。)
  • 关于函数内定义函数的问题:

    除了增加编译器的难度不会有任何用处,所以C语言不支持在函数内部定义函数的

输入缓冲区:

  • %d格式输入,默认分隔符是所有的 white-spaces(空格、回车、制表);
    %c格式输入,则按ASCII字符考虑,无分隔符。可能会受到之前输入的影响,必要时用fflush(stdin);清除缓冲区;
    %s 是 字符串格式,默认分隔符是所有的 white-spaces,输入后自动加入结束符"\0"。
  • 世界上首次提出存储程序计算机体系结构的是 ——冯诺依曼
  • 机器语言和汇编语言都属于低级语言
  • 世界上第一台基于冯·诺依曼结构的计算机(即存储程序计算机)由莫里斯·威尔克斯(Maurice Vincent Wilkes)于1946年研发,1949年正式投入运行。 这台计算机叫做延迟存储电子自动计算器(Electronic Delay Storage Auto-matic Calculator),缩写为EDSAC。
  • ENIAC,世界上第一台电子计算机,占地170平方米,重达30吨,耗电功率约150千瓦每时,每秒钟可进行5000次运算。被美国国防部用来进行弹道计算。

作业二:变量定义/读/写与数据的存储表示

  • 1-4:C语言中的结束符是以分号来结束的,一个分号就代表一条语句
  • 已知字母A的ASCII码为十进制数65,且ch为字符型变量,则执行语句ch='A'+'6'-'3';后,ch中的值为__。
  • 数字字符和整数值之间的转换:
    数字字符 - ‘0’ = 整型数值
    ‘9’ - ‘0’ =9;

同理:两个字符型变量相减之后的结果 应为整数

已知字母A的ASCII码为十进制数65,且ch为字符型变量,则执行语句ch='A'+'6'-'3';后,ch中的值为 68

但是若以%c输出那么结果会是D

三、填空题:

补码反码的表示以及IEEE754标准
  • 答案:4-4
实数的输入
scanf 函数输入实数时所使用的格式限定符
float
%f
double
%lf
long double 
%Lf
实数的输出
printf 函数输出实数时所使用的格式限定符
float
%f
double
%lf(或者%f)

作业3–运算符表达式与简单C程序

  • 2-5 5>3>1 运算符==>==是二元运算符,从左向右计算 1>1 所以最后结果为 0;
  • 2-6 逗号也是一种运算符 感兴趣可以查一下;
  • 关于标识符:
    标示符是有数字,字母和下划线组成,但标示符的第一个字符必须是字母或者下划线。 c语言的标示符分为三类: 1,关键字,如:int,static等等,具有特定的含义,不能做他用。 2,预定义标示符,如:库函数的名字(像printf,putchar等等)和预编译处理命令(像define,include等),为了避免误解,建议用户不要将这些做他用。 3,用户标示符,由用户自定,但不能与关键字和预定义标示符相同。还应做到“见名知义”。 最后,在标示符中,大小写字母代表不同的意思!(44个C语言关键字

    $$ 和下划线也可以单独作为标识符来使用,~ 这种奇奇怪怪的肯定是不行

  • 补码:负数的补码就是在起绝对值的基础上取反,再加1
  • 左值与表达式的值

作业4–选择与循环结构程序设计(Level 1)

  • 解析:
    • 2-2 C语言中不等于用 != 表示而不是==<>==,a=0 为赋值
    • C语言中for循环里面必须要有两个分号,初始条件可以提前在循环外设定而不写入

作业6–编程三部曲

  • 区别多层与多次 break向外跳一层,而continue是一次 ,两者只在循环中使用(循环中嵌套的if也是循环的范围)
  • 使用while语句时要记得对表达式中的值进行更新,避免死循环

作业8-变量作用域与递归程序设计

  • 解析:
#include<stdio.h>
int x = 3, y = 8;
void swap (){
    int z;
    z = x; x = y; y = z;
    printf (" %d , %d \n", x, y);
}
int main() {
    int x = 5, y = 7;
    swap ();
    printf (" %d , %d \n", x, y);
    return 0;
}
  • void 函数 类型为void表示不返回任何数值,
    定义的函数就是为了完成一系列功能的:
    1. 比如输入数据输出数据,这种情况是不需要返回值给主函数的,就像这个题目
    2. 指针操作数据也是不用返回数值的,因为通过指针访问数据是可以通过==*P==直接修改变量数值的,自然就不需要再把值返回给主函数
  • 第二个需要注意的地方就是函数每次内调用都会开辟一片新的存储空间用来存储子函数中的内容,如果函数是有返回值的函数(比如int double之类),那可以在子函数加工完成之后把内容再返回主函数,但如果子函数是void类型并且没用到指针,那么子函数和和主函数就是互不相干的两个区域,子函数一旦调用完成之后,存储空间就会释放,无法与主函数发生联系。此题目就是这样
    此处在第10行调用函数,进入子函数内 子函数定义了一个临时变量用来交换子函数中的两个数,交换完成并输出8, 3,然后存储空间释放,回到主函数11行,在打印主函数内存中的内容5,7

作业9–二维数组操作

因为只是判断这里就不写答案只是整理一下重点内容

  • 定义一个数组a[10],元素下标从0开始,对其初始化时可以部分初始化(后面未指定部分为0)也可以
  • 关于二维数组,二维数组的元素在内存中按行/列方式存放,即先存放第0行的元素,再存放第1行的元素……其中每一行的元素再按照列的顺序存放
    数组名[行下标] [列下标]
    将二维数组的行下标和列下标分别作为循环变量,通过二重循环,就可以遍历二维数组,即访问二维数组的所有元素。由于二维数组的元素在内存中按行优先方式存放,将行下标作为外循环的循环变量,列下标作为内循环的循环变量,可以提高程序的执行
  • 关于数组名与指针常量的问题:
    在C/C++中,数组类型跟指针类型是两种不同的派生类型,数组名跟指针是两种不同类型的实体,把数组类型的实体说成“是”另一个类型的实体,本身就是荒谬的;–《C和指针》

作业11-指针的概念和用法

一、判断题:

此处需要注意的地方就是:
  • 数组名是一个常量和定义的地址变量不同,他不能被赋值
  • 关于C语言指针的运算:指针只有加减操作,没有乘除操作。指针可以加常数、减常数;相同类型的指针可以相减,不可以相加,(指针又叫做地址,本质就是一个数字,相加减还可以表示指针访问位置的移动,而相乘没有意义)
  • 语句int *pprintf("%d",*p);中的*p含义
    int * 是一个整体 是一种数据类型 , 而printf中==*== 自己是一个单独的整体 表示解引用

作业12-结构体

一、判断题:

  • 结构体成员的类型可以是基本数据类型或者结构体类型等复合类型
  • 结构体作为一种数据类型也有他自己的数组定义
  • 指向运算符 ->
    p为当前结构体的指针
    p->num: (*p).num 即表示当前结构体num中存放的num变量的内容
    *p->next: (p).next 即表示当前结构体next中所存放的地址
    p->next=r : 表示将r 的地址赋给next,让next指向结构体变量 即实现链表元素的链接

二、单选题:

2-3 题干有问题
2-3 设有如下定义,则对data中的a成员的错误引用是(C)。 
struct sk
{ 
int a; float b; 
} data, *p=&data;

A   (*p).data.a
B   (*p).a
C    p->data.a
D    p.data.a

补充:未解决的问题

i++与++i的输出:输出顺序不同导致的表达式的值就不同

#include<stdio.h>
int main()
{
    int i=0;
    printf("%d %d\n",++i,i++);
    return 0;
}
输出结果为 2,0
分析:
  • 在gcc编译器中,printf语句从后向前执行,先执行i++
  • i++: 先执行操作后+1 ——》输出为0,后i变成1;
    ++i :先+1后参与操作 i先加1变成2,后输出;
  • 另外i++优先级高于++i ,两种运算符都是单操作数运算符,不能对表达式求值,会编译出错

    例如:(-i)++或者–i++

7-3 找出最小值

#include<stdio.h>
int main()
{
	int n,k,min;
	scanf("%d",&n);
	for(int i=0;i<n;i++)
	{
		scanf("%d",&k);
		if(i==0)
			min=k;
		if(min>k)
			min=k;
	}
	printf("min=%d",min);
	return 0;
 } 

补充: 十进制转换二进制

// 一个递归的问题,可以分为回溯和地推两个部分,在解决转化二进制时,特别是输入一个比较大的
// 整数时,要对这个整数不断地除2取余,最后再倒序输出二进制数字;而在程序运行时回溯过程是
// 用来对十进制除2,直到打到边界,在进行递推由边界开始递推倒序输出取余后的数字,
// 即为相应的二进制数字
void dectobin(int n)
{
    if(n == 0 || n == 1)
        printf("%d", n);//设置递归边界
    else
    {
        dectobin(n / 2);//十进制取余
        printf("%d", n % 2);
    }
}

补充:使用函数输出一个整数的逆序数

核心代码:
int reverse(int number)
{
    int temp=0;
    while(number!=0)//无论正负都进入循环,不必再进行分类
    {
        temp=temp*10+number%10;//递推法求逆序数
        number=number/10;
    }
    return temp;
}
  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值