笔试-LFK-C语言

笔试-LFK-C语言,第1张

这里写目录标题
    • 选择题(10)
    • 填空题(8)
    • 编程题(1)
    • 总结

选择题(10)
  • 1.以下循环执行次数是1次的是( C )。

A. 	for(int i = 10, j = 1; i = j = 0; i++, j--)
B. 	do
	{
	}while(0)
C.	int i = 1;
	while(i--)
	{
	}
D.	unsigned char i;
	for(i = 255; i < 256; i++)
  • 解释
    A. for循环中的判断语句i=j=0,写成了赋值语句,因此该处的判断为false,不循环。


    B. 循环一次,但是代码会报错,while(0)后面少一个分号。


    C. ✔。


    D. char的范围是0-255,因此条件一直成立,上述为死循环。

  • 2.以下说法正确的是(B)。

A. break语句只用于循环体中。

B. continue语句只用于循环体中。

C. break是无条件跳转语句,continue不是。

D. breakcontinue的跳转范围不够明确,容易产生问题。

  • 解释
    A. break还可用于switch…case…。


    B. ✔。


    C. 两者都为无条件跳转,另外goto和return也是。


    D. 是明确的,break跳出当前循环,continue跳出本次循环,执行下一次循环。

  • 3.64位系统以及64位编译器下,下面的代码输出中哪写正确(AD)。

void fun(int str[])
{
	int a = sizeof(str);
}
int temp[10] = {1, 2, 3};
int b = sizeof(temp);
fun(temp);

A. a = 8

B. a = 40

C. b = 12

D. b = 40

  • 解释
    b是10个int所占的字节,一个int占4个字节,a为指针,为8字节。

  • 4.题未知
  • 5.下面程序片段的输出是(A)。

int a[] = {1, 2, 3, 4, 5};
int *ptr = (int*)(&a + 1);
print("%d, %d", *(a + 1), *(ptr - 1));
A. 2, 5

B. 2, 1

C. 1, 2

D. 5, 1

  • 解释
    (a + 1)表示数组的第二个数,a为首地址,&a也为首地址,星号表示从地址解析出值。


    &a+1,与上表示不一样,加一表示加上a数组的长度,如以下程序中的第四行输出结果,首地址为6422016,&a+1为6422036,在首地址上加了4 * 5 = 20个字节,若是加&a+2,则加上40。


    另外
    (ptr-1),减1,是减少4个字节,int的话,就是向前移动一个数字,所以第二个答案是5,减2的话答案就是4了。


    如果数组是char类型的,一个char占一个字节,*(ptr-1)中的减1,也是减少四个字节,但是主义char类型的有结束符号,因此减一后的答案是3。

int main()
{
    int a[] = {1, 2, 3, 4, 5};
    //char a[] = "12345";
    int *ptr = (int*)(&a+1);
    printf("res: %d, %d\n", *(a+1), *(ptr-1));

    printf("%d, %d\n", (a+1), (ptr-1));
    printf("a: %d, a+1: %d\n", a, a+1);
    printf("&a: %d, &a+1: %d\n", &a, &a+1);
    printf("a: %d, ptr: %d", &a+1, ptr);
    return 0;
}
//结果
res: 2, 5
6422020, 6422032
a: 6422016, a+1: 6422020
&a: 6422016, &a+1: 6422036
a: 6422036, ptr: 6422036

  • 6.假设有一颗二叉树的后序遍历为DBFEGCA,中序遍历为DBAFECG,则先序遍历为(A)。

A. ABDCEFG。

B. ADCBEFG。

C. ADBFEGC。

D. ABDCFEG。

  • 解释
    后序遍历,(左子树)(右子树)(根节点)。


    中序遍历,(左子树)(根节点)(右子树)。


    前序遍历,(根节点)(左子树)(右子树)。


    树的重建:先重前或者后序遍历中寻找根节点(前序中第一个就是根节点,后序中最后一个是根节点),然后再中序遍历中找出左子树和右子树,再重复以上 *** 作,即可恢复二叉树。

  • 7.进程间通信(IPC)的方法有()。

A. 匿名通道。

B. 有名通道。

C. 条件变量。

D. 共享内存。

E. 互斥量。

  • 解释
    进程间通信有:管道(匿名管道,命名管道),消息队列,信号量,信号,共享内存,Socket
    详细解释参考这里
  • 8.数字推理:1/17, 1/7, 4/11, 1 (B)
A. 15

B. 16/5

C. 8

D. 7/2

  • 解释
    将数展开成:1/17, 2/14, 4/11, 8/8, 16/5
    分子为2的次方,1 2 4 8 16 32
    分母依次减三
  • 9.题未知
  • 10.题未知
填空题(8)
  • 1.CPU执行一段程序时,cache完成存取的次数为2500次,主存完成存取的次数为625次,已知cache存取周期为30ns,主存为180ns,求cache、主存系统的效率和平均访问时间 60 ns

  • 解释
    存取总次数:2500+625 = 3125
    命中率:H = 2500 / 3125 = 0.8
    主存慢于cache的倍率:r = 180 / 30 = 6
    访问效率:e = 1 ( r + ( 1 − r ) H ) \frac{1}{(r + (1-r)H)} (r+(1r)H)1 = 1 ( 6 + 0.8 ∗ ( − 5 ) ) \frac{1}{(6 + 0.8*(-5))} (6+0.8(5))1 = 50%
    平均访问效率:T = t/e = 30ns/50% = 60ns
  • 2.以下程序打印的结果(m = 5, n = 6
#include 
int main()
{
	int i = 2, j = 5, m = 0, n = 0;
	if ((i = 1)||(j != 5)) m = 5;
	else m = 6;
	if ((i & j) != 1) n = 5;
	else n = 6;
}
  • 解释
    在第一个if语句中,i = 1为赋值语句,且为true,故m = 5。


    在第二个if语句中,i = 1(001), j = 5(101),两个相与,结果为001,故判断结果为false,n = 6。

  • 3.定义一个返回值类型为bool,有一个int型参数a的纯虚函数func:
    virtual bool func(int a) = 0;

  • 4.派生类覆盖基类的虚函数,实现接口的重用,且返回值类型相同,称为函数的重写;将语意相近的几个函数用同一个名字表示,但是参数列表(参数的类型,个数,顺序)不同,成为函数的重载

  • 5.写出四种进程间通信方式:
    消息队列, 信号量,信号,Socket,内存共享,管道

  • 6.p为无符号整型数据,len为p数组长度,请完成空白处程序,如存在p的低16位为零,高16位不为零返回1,否则返回0.

int fun(unsigned int *p, int len)
{
	for(int i = 0; i < len; i++)
	{
		if ==((p & 0x0000FFFF == 0) && (p & 0xFFFF0000) != 0)==
		{
			return 1;
		}
		p++;
	}
	return 0;
}
int main()
{
	int res = 0;
	unsigned int test[] = {{0x34e20000,0x005600ff,0x1000fee3, 0x00002380};
	res = fun(&test[0], ==sizeof(test) / sizeof(test[0])==);
}
  • 解释
    上述代码中“====”中间的为所填的程序
    ((p & 0x0000FFFF == 0) && (p & 0xFFFF0000) != 0)
    sizeof(test) / sizeof(test[0])
  • 7.采用64位的编译器,下面程序的结果是d1 = 16, d2 = 4, d3 = 8

struct da1{
	int a;
	char *b;
}
struct da2{
	int a;
	char b[0];
}
struct da3{
	int a;
	char b[1];
}
int main()
{
	struct da1 d1;
	struct da2 d2;
	struct da3 d3;
	printf("d1 = %zd", sizeof(d1));
	printf("d2 = %zd", sizeof(d2));
	printf("d3 = %zd", sizeof(d3));
}
  • 解释
    8+8 = 16, 4+0 = 4, 4+4 = 8。

  1. 结构体成员的偏移量必须是当前成员大小的整数倍
  2. 结构体的大小必须满足所有成员(不考虑数组和内套结构体)的整数倍
  3. 注意最后的结果不考虑结构体成员中数组大小的整数倍
    结构体的大小结算参考这里,变量占字节大小参考这里。

  • 8.使用冒泡排序(我感觉题错了,应该是选择排序叭)从小到大,修改下面程序的错误。

void sort(int *p, int n)
{
    int *q, *k;
    for (q = p; q < p + n -1; q++){
        for (k = q + 1; k < p + n; k ++){
            if (*k < *q){
                int t = q; //1
                *q = *k;
                *k = t;}}}
    return 0; //2
}
int main()
{
    int len = 7;
    int arr[len] = {23, 34, 46, 43, 86, 57, 22};
    sort(&arr, len); // 3
    for(int i = 0; i < 7; i++) printf("%d ", *arr+i); // 4
    return 0;
}

int t = q; -> int t = *q;
return 0; -> return ;
sort(&arr, len); -> sort(arr, len);
printf("%d “, *arr+i); -> printf(”%d ", *(arr+i));

修改后程序

void sort(int *p, int n)
{//选择排序
    int *q, *k;
    for (q = p; q < p + n -1; q++){
        for (k = q + 1; k < p + n; k ++){
            if (*k < *q){
                int t = *q; //1
                *q = *k;
                *k = t;}}}
    return ; //2
}
int main()
{
    int len = 7;
    int arr[len] = {23, 34, 46, 43, 86, 57, 22};
    sort(arr, len); // 3
    for(int i = 0; i < 7; i++) printf("%d ", *(arr+i)); // 4
    return 0;
}

编程题(1)

给定一个循环链表,删除其中的一个节点,在返回一个任意节点。


请定义函数:pnode delete_node(pnode list, pnode node)
数据节点为
typedef struct n
{
int data;
struct n *next;
} *pnode;
参考这里

pnode delete_node(pnode list, pnode node)
{
	//循环遍历循环链表,当下一个节点指向头结点时,表示遍历完
	Pnode cur;
	Pnode target;
	if(cur == NULL)
	{
		print(“这是个空指针,无法删除”)
		return NULL;
}
	if (list == node)
	{//删除头结点
		//寻找尾节点target
		for(target = list; target->next != list; target = target->next);
		cur = list; //存下头结点
		list = list->next; //记录开始节点的下一个
		target->next = list; //最后一个节点指向下一个节点
		free(cur); //删除节点
		return list
	}
	else
	{//删除其他节点
		for(target = list; target->next != node && target->next != list; target = target->next);
		//找到了node,则target是node的前一个节点,找到不到的话,则target和头节点相等
		if(target->next == list)
		{
			//没有寻找的节点,返回头结点
			return list;
		}
		else
		{//找到node节点了
			//删除中间的节点, 则找该节点的前一个节点target
			cur = target->next;
			target->next = target->next->next: //
			free(cur); //删除尾节点
			return list;
		}
	}
}
总结

总的来说,还是挺基础的,考的比较细,但是不好做,当时做的可差了。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/673423.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-04-19
下一篇 2022-04-19

发表评论

登录后才能评论

评论列表(0条)

保存