ACAT2021纳新题解(C语言)

ACAT2021纳新题解(C语言),第1张

ACAT2021纳新题解(C语言)

ACAT2021纳新题解(C语言)
  • 说明:
  • 题目
  • 参考
    • 1. 下列选项正确的是(B.7)
    • 2.下列选项正确的是(B.64)
    • 3.请分析下列代码的运行结果(1 5),并解释其原因。
    • 4.请分析下列代码的运行结果(111),并解释其原因。
    • 5. 分析下列代码,请计算 x,y,z的大小(16 16 24)
      • 答案
      • 扩展:
    • 6.已知 int a[3] [4],请不用中括号使用数组索引值打印出a[1] [2],printf("%d",*(*(a+1)+2));printf("%d",*(*a+6));
    • 7.请分析以下代码的运行结果(-1或0或1),并解释其原因。
      • 答案
      • 补充:printf的返回值的含义:输出字符的数量
    • 8.你知道哪些排序算法?你知道它们是怎样实现的吗?(大致思路)
      • 简单选择排序
      • 冒泡排序
        • 冒泡排序1.0版
        • 冒泡排序2.1版
        • 冒泡排序2.2版
      • 补充:简单桶排序
    • 9.字符串翻转
      • 答案
      • 扩展:去掉ch变量
        • 用加减法实现交换
        • 用异或实现交换
      • 补充:用递归实现
    • 10. 单链表逆置,要求在原有空间进行逆置。
      • 答案

说明:
本试题一共分为12道题,考核点全部以C语言为主,难度有层次划分,希望你尽最大努力完成,我们
不需要你每道题都能得到正确答案,但希望你能有良好的学习态度。我们期待在面试那天与你相
遇!
(本测试题目省略#include…,编程题只用写出核心代码,你也可以在面试时带上U盘或者电脑直接展
示你的结果!)
题目

ACAT2021纳新题目(C语言)

参考 1. 下列选项正确的是(B.7)
考点:运算符
#include
#include
int main(void){
    int i=3;//3
    int k=4;//4
	k += (k++) - (--i);//5+  4(5)- 2
	printf("%d",k);
    return 0;
}

a)6		b)7		c)8		d)9
2.下列选项正确的是(B.64)
考点:运算符<<:位运算左移
<<= 赋值运算符
? : 条件运算符
#include 
int main() {
    int a = 2, b = 3;
    printf("%dn", a <<= a < b ? a + b : a - b ); 
    //a < b ? a + b : a - b 为5  a<<=5 -->  a=a<<5=2<<5=2*2^5=64
    
    return 0;
}


A)-32   	b) 64	   c)2*(2^-5)		d)1*(2^-5)
3.请分析下列代码的运行结果(1 5),并解释其原因。
考点:运算符的优先级和结合性
下表按照题目中运算符出现顺序排列
优先级运算符含义结合性15,逗号运算符自左至右2++自增运算符自右至左10||逻辑或运算符自左至右14=赋值运算符自右至左2--自减运算符自右至左

注意:在逻辑表达式的求解中,并不是所有的逻辑运算符都要被执行,只有在必须下一个逻辑运算符才能求出表达式的解时,才执行该运算符。

例如:
int x=-1;
执行++x||++x||++x后,x的值是多少?
分析:根据逻辑“||”自左至右的结合性,先计算第一个“”左边的运算对象++x,得到结果为0。
对于“||”运算符来说还不能确定这个表达式的值,必须再计算右边的++x,得到结果为1。
此时第一个“||”结合的表达式的值就为1,这样无论第二个“||”运算符后面的运算对象值为多少,整个表达式的值已经确定为1。所以不需再计算第三个++x了,因而x的值为1。

说回题目

int main(int argc, char const* argv[])
{
    int a = 0, b = 5;
    ++a || ++b, a - b;//a变成1 ||表达式的值为1,后面的++b不会执行
    b = b--;//b=5 --
    printf("%d %dn", a, b);//1 5
    return 0;
}
4.请分析下列代码的运行结果(111),并解释其原因。
考点:运算符
# include 
int main() {
	int a = 0;//a为0
	int b = 0 == a;//0==a的值为1 ,b为1
	int c = -1;//c为1

	if (a = 1) {//a赋值为1 
		c = a && b;//c=1&&1=1
	}

	printf("%d%d%d", a, b, c);//111
	return 0;

}
5. 分析下列代码,请计算 x,y,z的大小(16 16 24)
考点:struct 的内存对齐

以下引用自https://blog.csdn.net/weixin_30432007/article/details/97729396

1、字节对齐的细节和编译器实现相关,但一般而言,如在windows下,就VC而言,满足一下三个准则:

1) 结构体变量的首地址能够被其最宽基本类型成员的大小所整除;

2) 结构体每个成员相对于结构体首地址的偏移量(offset)都是成员大小的整数倍,如有需要编译器会在成员之间加上填充字节(internal adding);
即:在默认情况下,VC规定各成员变量存放的起始地址相对于结构的起始地址的偏移量:sizeof(类型)或其倍数

3) 结构体的总大小为结构体最宽基本类型成员大小的整数倍,如有需要编译器会在最末一个成员之后加上填充字节(trailing padding)
即:最大sizeof(类型)的整数倍
类型
对齐方式(变量存放的起始地址相对于结构的起始地址的偏移量)
Char   偏移量必须为sizeof(char)即1的倍数
int    偏移量必须为sizeof(int)即4的倍数
float  偏移量必须为sizeof(float)即4的倍数
double 偏移量必须为sizeof(double)即8的倍数 
Short  偏移量必须为sizeof(short)即2的倍数

说回题目

答案
# include 
#pragma pack (8) 
int main(){
 
    struct x{			//16     2*8
        int a;			//4      Bytes ,此时偏移量为4
        char b;			//1      Byte  ,偏移量4是1的倍数,此时偏移量为5
        double c;		//8  	 Bytes ,此时偏移量5不是8的倍数,填充3,使偏移量为8,然后为c开辟8个空间,此时偏移量为16
    }; 
    struct y{			//16     2*8
        float b;		//4		 Bytes ,此时偏移量为4
        int a;			//4      Bytes ,偏移量4是4的倍数,此时偏移量为8
        double c;		//8  	 Bytes ,偏移量8是8的倍数,此时偏移量为16
    };
    struct z{			//24     3*8
        int a;			//4      Bytes ,此时偏移量为4
        double c;		//8   	 Bytes ,偏移量4不是8的倍数,填充4,此时偏移量为8,然后为c开辟8个空间,此时偏移量为16
        char b;			//1      Byte , 此时偏移量16是1的倍数,偏移量为17,结构体的总大小为结构体最宽基本类型成员大小的整数倍,即需是8的整数倍,需要编译器会在最末一个成员之后加上填充字节(trailing padding),填充8*3-17=7个,此时偏移量为24
    };
    

    printf("%dn",sizeof(struct x)); //16
    printf("%dn",sizeof(struct y)); //16
    printf("%dn",sizeof(struct z)); //24
}
扩展:
共用体内存大小:为最大元素的内存大小
指针内存大小:在64bits机器中所有指针内存大小为8字节
数组内存大小:数组和数组长度个单独数组元素类型相等
#include
union UNode{ 
	char ch;     	// 1     Byte  
    int in;        	// 4      Bytes
    char *p; 		//8  在64bits机器中所有指针8字节
 };
 struct SNode{
	char ch;     	// 1     Byte
    short sh;    	// 2     Bytes
    int in;       	// 4      Bytes
    float f;      	//4
    double db;		//8
    char *p;   		//8 在64bits机器中所有指针8字节
    char arr[5];	//数组和5个单独类型相等,相当列出5个char在根据原则对齐

 };
 int main(){
 	printf("%d",sizeof(struct SNode));//40
 	printf("%d",sizeof(union UNode));//8
 }
6.已知 int a[3] [4],请不用中括号使用数组索引值打印出a[1] [2],printf("%d",((a+1)+2));printf("%d",*(*a+6));
考点:指针和数组
*(a+i)==a[i]
数组元素的存储地址计算
# include 
 
int main(){
	int a[3][4];
	int i,j;
	for(i=0;i<3;i++){
		for(j=0;j<4;j++){
			a[i][j]=i*j;
		}		
	}
	for(i=0;i<3;i++){
		for(j=0;j<4;j++){
			printf("%d",a[i][j]);
		}
		printf("n");
	}
	

	
	printf("%dn",&a[1][2]);
	printf("%dn",a[1][2]);
	
	printf("答案n"); 
	printf("%dn",*(*(a+1)+2));
	printf("%dn",*(*a+6));
	
	printf("扩展n");
	printf("%dn",&a[0][0]);
	printf("%dn",a);//a存的是首元素 a[0][0]的首地址 ,其实还存了它的类型 int 
	printf("%dn",*a);/
	for(i = 0;i<=n/2;i++){		
			ch=s[i];
			s[i]=s[n-1-i];
			s[n-1-i]=ch;
		
	}

	

	printf("%s", s);
	return 0;

}
扩展:去掉ch变量 用加减法实现交换
# include  
# include  
int main() {
	
	char s[32];
	scanf("%s", s);
	int n = strlen(s);
	int i; 

	
	i=0;
	n=n-1;
	while(i 
用异或实现交换 
# include  
# include  
int main() {
	
	char s[32];
	scanf("%s", s);
	int n = strlen(s);
	int i; 

	
	i=0;
	n=n-1;
	while(i 
补充:用递归实现 
#include
void reverseSentence();

int main(){
	printf("输入:");
	reverseSentence();
	
	return 0;
} 
void reverseSentence(){
	char c;
	scanf("%c",&c);
	
	if(c != 'n'){
		reverseSentence();
		printf("%c",c);
	}
}
10. 单链表逆置,要求在原有空间进行逆置。 答案
#include
#include
#include 
#define DataType int
#define ERROR 0
#define TRUE 1

typedef struct node{
	DataType data;
	struct node *next;
}LNode,*linkList;

//1.建立单链表
//尾插法建立单链表 
linkList CreatByBear(){
	linkList H=(linkList)malloc(sizeof(LNode)); //生成头结点 
	H->next=NULL;		//空表 
	LNode *s, *r=H;
	int x;
	printf("输入(-1结束)"); 
	scanf("%d",&x);
	while(x!=-1){
		s=(linkList)malloc(sizeof(LNode));
		s->data=x;
		
		r->next=s;
		r=s;		//r指向新的尾结点 
		printf("输入(-1结束)"); 
		scanf("%d",&x);
	}
	 r->next=NULL;   
	 return H;
}



//单链表的逆置
void Reverse(linkList H){  
	LNode * p,*q;
	p=H->next;		//p指向第一个数据结点
	H->next= NULL;		//将原链表置为空表H
	while(p){
		q=p;
		p=p->next;
		q->next=H->next;	//将当前结点插到头结点的后面(头插)
		H->next=q;
	}

} 

//遍历输出 
void OutPut(linkList head){
	LNode *p;
	p=head->next;
	while(p){		
		printf("(%d)n",p->data);
		p=p->next;
	}
} 


void main(){
	//建立 
	linkList h=CreatByBear();
	printf("输出"); 
	OutPut(h);
	Reverse(h);
	printf("逆置");
	OutPut(h); 
} 

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

原文地址: https://outofmemory.cn/zaji/4749287.html

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

发表评论

登录后才能评论

评论列表(0条)

保存