2024-05-23_结构体概念等作业

1.如有以下代码:

struct student
{
  int num;
  char name[32];
  float score;
}stu;

则下面的叙述不正确的是:( )
A.struct 是结构体类型的关键字
B.struct student 是用户定义的结构体类型
C.num, score 都是结构体成员名
D.stu 是用户定义的结构体类型名
解析:
A:正确,在C语言中需要自定义类型时,要用到struct关键字
B:正确:在C语言中,用struct定义的结构体,定义结构体类型变量时,需要用struct student
C:正确:结构体中的变量名称,称之为结构体的成员
D:错误:stu是定义的结构体类型变量,不是名称,如果想要让stu为结构体类型名称时,必须在结构体定义时添加 typedef关键字。

2.下面程序的输出结果是:( )

struct stu
{
    int num;
    char name[10];
    int age;
};

void fun(struct stu *p)
{
	printf("%s\n",(*p).name);
	return;
}

int main()
{
	struct stu students[3] = {{9801,"zhang",20},
							  {9802,"wang",19},
                              {9803,"zhao",18} };
    fun(students + 1);
    return 0;
}

A.zhang
B.zhao
C.wang
D.18
答案:C。在main函数中先定义了一个stu结构体类型的数组students,students指向结构体的起始位置,students+1 表示该数组中下标为 1 的元素,因此fun的形参实际指向的是students数组中的第二个元素,故打印的是wang。

3.结构体访问成员的操作符不包含:( )
A… 操作符
B.-> 操作符
C.* 解引用操作符
D.sizeof
答案:D。
A:正确,结构体类型变量访问结构体中成员时,使用.操作符;
B:正确,指向结构体类型变量的指针访问结构体中成员时,使用->操作符;
C:正确,指向结构体类型变量的指针也可以通过.方式访问成员,只不过要先通过*对该指针解引用;
D:错误,sizeof是求结构体类型大小的

4.下面程序要求输出结构体中成员a的数据,以下不能填入横线处的是( )

#include <stdio.h>

struct S
{
	int a;
	int b;
};
int main()
{
	struct S a, *p = &a;
	a.a = 99;
	printf("%d\n", ________)
	return 0;
]

A.a.a
B.*p.a
C.p->a
D.(*p).a
答案:B。结构体类型变量需要访问其成员时,用.运算符,如果是指向结构体变量的指针访问时,需要用->,或者先对指针解引用,取到指向的结构体类型的变量,再通过.访问,但是要注意优先级。

5.在VS2013下,默认对齐数为8字节,这个结构体所占的空间大小是( )字节。

typedef struct
{
	int a;
	char b;
	short c;
	short d;
}AA_t; 

A.16
B.9
C.12
D.8
答案:C.12。因为,int a 占4个字节,内存0-3;char占1个字节,内存4;short占2个字节,内存6-7,8-9;综上,结构体占12个字节(因为必须是4的整数倍)。

6.在32位系统环境,编译选项为4字节对齐,那么sizeof(A)和sizeof(B)是( )

struct A
{
	int a;
	short b;
	int c;
	char d;
};

struct B
{
	int a;
	short b;
	char c;
	int d;
};

答案:C,16,12.
解析1:int a;占0-3字节
short b;占4-5字节,
int c;占8-11字节
char d;占12字节;所以它们四个占0-12字节,共三个字节,因此结构体大小为16个字节。
解析2:int a; 0-3
short b; 4-5
char c; 6
int d; 8-11,
所以一共占12个字节。
官方解答:两个结构体都是向int看齐。结构体A中,a独自对齐一个4字节,b+c超过了4字节,所以b独自对齐一个4字节,c独自对齐一个4字节,剩下一个d独自对齐一个4字节,共16字节。结构体B中,a独自对齐一个四字节,b+c+d才超过了4字节,所以b和c一起对齐一个4字节,d单独对齐一个4字节,共12字节,故选C。

7.下面代码的结果是:( )

#pragma pack(4)/*编译选项,表示4字节对齐 平台:VS2013。语言:C语言*/
//假设long 是4个字节
int main(int argc, char* argv[])
{
  struct tagTest1
  {
    short a;
    char d; 
    long b;   
    long c;   
  };
  struct tagTest2
  {
    long b;   
    short c;
    char d;
    long a;   
  };
  struct tagTest3
  {
    short c;
    long b;
    char d;   
    long a;   
  };
  struct tagTest1 stT1;
  struct tagTest2 stT2;
  struct tagTest3 stT3;

  printf("%d %d %d", sizeof(stT1), sizeof(stT2), sizeof(stT3));
  return 0;
}
#pragma pack()

A.12 12 16
B.11 11 11
C.12 11 16
D.11 11 16
答案:
short a;0-1
char d; 2
long b; 4-7
long c;8-11
12
long b; 0-3
short c;4-5
char d;6
long a;8-11
12
short c;0-1
long b;4-7
char d; 8
long a;12-15
16
所以答案为A,12 12 16.

官方解答:三个结构体都向最长的4字节long看齐。第一个a+d+b才超过4字节,所以a和d一起对齐一个4字节,剩下两人独自占用,共12字节,第二个同理c,d合起来对齐一个四字节,也是12字节。第三个因为c+b,d+a都超过4字节了,所以各自对齐一个4字节,共16字节。故选A。

8.有如下宏定义和结构定义( )

#define MAX_SIZE A+B
struct _Record_Struct
{
  unsigned char Env_Alarm_ID : 4;
  unsigned char Para1 : 2;
  unsigned char state;
  unsigned char avail : 1;
}*Env_Alarm_Record;
struct _Record_Struct *pointer = (struct _Record_Struct*)malloc(sizeof(struct _Record_Struct) * MAX_SIZE);

当A=2, B=3时,pointer分配( )个字节的空间。
A.20
B.15
C.11
D.9
答案:说明:结构体向最长的char对齐,前两个位段元素一共4+2位,不足8位,合起来占1字节,最后一个单独1字节,一共3字节。另外,#define执行的是查找替换, sizeof(struct _Record_Struct) * MAX_SIZE这个语句其实是3*2+3(要考虑优先级),结果为9,故选D。

9.下面代码的结果是( )

int main()
{
  unsigned char puc[4];
  struct tagPIM
  {
    unsigned char ucPim1;
    unsigned char ucData0 : 1;
    unsigned char ucData1 : 2;
    unsigned char ucData2 : 3;
  }*pstPimData;
  pstPimData = (struct tagPIM*)puc;
  memset(puc,0,4);
  pstPimData->ucPim1 = 2; 
  pstPimData->ucData0 = 3;
  pstPimData->ucData1 = 4;
  pstPimData->ucData2 = 5;
  printf("%02x %02x %02x %02x\n",puc[0], puc[1], puc[2], puc[3]);
  return 0;
}

A.02 03 04 05
B.02 29 00 00
C.02 25 00 00
D.02 29 04 00
答案:
puc是一个char数组,每次跳转一个字节,结构体不是,它只有第一个元素单独享用一字节,其他三个元素一起共用一字节,所以puc被结构体填充后,本身只有两个字节会被写入,后两个字节肯定是0,至此AD排除,然后第一个字节是2就是2了,第二个字节比较麻烦,首先ucData0给了3其实是越界了,1位的数字只能是0或1,所以11截断后只有1,同理ucData1给的4也是越界的,100截断后是00,只有5的101是正常的。填充序列是类似小端的低地址在低位,所以排列顺序是00 101 00 1。也就是0010 1001,即0x29,故选B。

10.编程题 变种水仙花数
描述
变种水仙花数 - Lily Number:把任意的数字,从中间拆分成两个数字,比如1461 可以拆分成(1和461),(14和61),(146和1),如果所有拆分后的乘积之和等于自身,则是一个Lily Number。

例如:

655 = 6 * 55 + 65 * 5

1461 = 1461 + 1461 + 146*1

求出 5位数中的所有 Lily Number。

输入描述:

输出描述:
一行,5位数中的所有 Lily Number,每两个数之间间隔一个空格。
在这里插入图片描述

//下面的代码是官方答案,上面图片中的代码有小缺陷
#include <stdio.h>
int main()
{
    int i = 0;
    for(i=10000; i<=99999; i++)
    {
        //判断i是否为lily number
        int j = 10;
        int sum = 0;
        int tmp = i;
        for(j=10; j<=10000; j*=10)
        {
            sum += (tmp%j)*(tmp/j);
        }
        if(sum == i)
            printf("%d ", i);
    }
    return 0;
}

11.编程题 序列中删除指定数字
描述
有一个整数序列(可能有重复的整数),现删除指定的某一个整数,输出删除指定数字之后的序列,序列中未被删除数字的前后位置没有发生改变。

数据范围:序列长度和序列中的值都满足
1

𝑛

50
1≤n≤50
输入描述:
第一行输入一个整数(0≤N≤50)。

第二行输入N个整数,输入用空格分隔的N个整数。

第三行输入想要进行删除的一个整数。

输出描述:
输出为一行,删除指定数字之后的序列。

//示例1
//输入:
6
1 2 3 4 5 9
4
//输出:
1 2 3 5 9

//示例2
//输入:
5
1 2 3 4 6
5
//输出:
//1 2 3 4 6

在这里插入图片描述

//下面代码是官方标准答案。上面图片中的方法也是正确的,代码量要小一点。
#include <stdio.h>


int main()
{
    int n = 0;
    int arr[50] = {0};
    int del = 0;
    scanf("%d", &n);
    int i = 0;
    for(i=0; i<n; i++)
    {
        scanf("%d", &arr[i]);
    }
    scanf("%d", &del);//要删除的元素
    int j = 0;
    for(i=0; i<n; i++)
    {
        if(arr[i] != del)
        {
            arr[j++] = arr[i];
        }
    }
    
    for(i=0; i<j; i++)
    {
        printf("%d ", arr[i]);    
    }
    return 0;
}
  • 36
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值