【C语言进阶】10. 习题①

2022-05-23-原码/反码/补码

1. printf函数接收类型

程序的执行结果为( )

int main()
{
  unsigned char a = 200;
  unsigned char b = 100;
  unsigned char c = 0;
  c = a + b;
  printf("%d %d", a+b,c);
  return 0;
}

A.300 300
B.44 44
C.300 44
D.44 300

【答案解析】
说明:printf在传入参数的时候如果是整形会默认传入四字节, 所以a+b的结果是用一个四字节的整数接收的,不会越界。而c已经在c = a + b这一步中丢弃了最高位的1,所以只能是300-256得到的44了。

※由于printf是可变参数的函数,所以后面参数的类型是未知的,所以甭管你传入的是什么类型,printf只会根据类型的不同将用两种不同的长度存储。其中8字节的只有long long、float和double(注意float会处理成double再传入),其他类型都是4字节。所以虽然a + b的类型是char,实际接收时还是用一个四字节整数接收的。另外,读取时,%lld、%llx等整型方式和%f、%lf等浮点型方式读8字节,其他读4字节。

在这里插入图片描述

2. 大小端字节序

题目名称:

unsigned int a= 0x1234;
unsigned char b=*(unsigned char *)&a;

32位大端模式处理器上变量b等于( )

题目内容: A .0x00 B .0x12 C .0x34 D .0x1234

在这里插入图片描述

3. char 字符类型循环

下面代码的结果是( )

int main()
{
  char a[1000] = {0};
  int i=0;
  for(i=0; i<1000; i++)
  {
    a[i] = -1-i;
  }
  printf("%d",strlen(a));
  return 0;
}

A.1000
B.999
C.255
D.256

a是字符型数组,strlen找的是第一次出现尾零(即值为0)的位置。
考虑到a[i]其实是字符型,如果要为0,则需要-1-i的低八位要是全0,
也就是问题简化成了“寻找当-1-i的结果第一次出现低八位全部为0的情况时,i的值”(因为字符数组下标为 i 时第一次出现了尾零,则字符串长度就是i)。
只看低八位的话,此时-1相当于255,所以i==255的时候,-1-i(255-255)的低八位全部都是0,也就是当i为255的时候,a[i]第一次为0,所以a[i]的长度就是255了,故选C

//-1 -2 -3 -4 -5.....-128 
//-129
//1000... 10000001 原码
//11111...01111110 反码
//11111...01111111 补码
// 发生截断  01111111 也就是127
// 所以是 : -1,-2,-3.....-128, 127 ,126,.....2,1,0 结束
// 127+128 = 255

4. 猜名次(for循环嵌套)

题目名称: 猜名次
题目内容: 5位运动员参加了10米台跳水比赛,有人让他们预测比赛结果:
A选手说:B第二,我第三;
B选手说:我第二,E第四;
C选手说:我第一,D第二;
D选手说:C最后,我第三;
E选手说:我第四,A第一;
比赛结束后,每位选手都说对了一半,请编程确定比赛的名次。

在这里插入图片描述

2022-05-30-字符指针

5. 指针赋值

下面哪个代码是错误的?( )

#include <stdio.h>
int main()
{
  int *p = NULL;
  int arr[10] = {0};
  return 0;
}

A.p = arr;
B.int (*ptr)[10] = &arr;
C.p = &arr[0];
D.p = &arr;

【答案解析】D
就数据类型来看,A左右两边都是int *,B左右两边都是 int (*)[10],C左右两边都是int *,D左边是 int *,右边是 int (*)[10]

6. 指针数组和数组指针

如何定义一个int类型的指针数组,数组元素个数为10个:( )
A.int a[10]
B.int (*a)[10]
C.int *a[10];
D.int (*a[10])(int);

【答案解析】C
要实现int的指针数组,首先要是数组 A为int数组, B为int数组的指针,C为int的指针数组,D为int(*)(int)函数指针的数组

7. 字符串左旋

字符串左旋
实现一个函数,可以左旋字符串中的k个字符。
例如:
ABCD左旋一个字符得到BCDA
ABCD左旋两个字符得到CDAB

要实现左旋那么创建的字符串就必须可修改,不能是常量字符串 char * 应该用字符数组char arr[ ]在这里插入图片描述

8. 在杨氏矩阵中找元素

杨氏矩阵
有一个数字矩阵,矩阵的每行从左到右是递增的,矩阵从上到下是递增的,
请编写程序在这样的矩阵中查找某个数字是否存在。
要求:时间复杂度小于O(N);

在这里插入图片描述
在这里插入图片描述

2022-06-01-函数指针数组

9. 回调函数的定义

关于回调函数描述错误的是( )
A.回调函数就是一个通过函数指针调用的函数
B.回调函数一般通过函数指针实现
C.回调函数一般不是函数的实现方调用,而是在特定的场景下,由另外一方调用。
D.回调函数是调用函数指针指向函数的函数。

【答案解析】D
“调用指针”、“指向函数”是什么鬼…… D选项简直逻辑鬼才! 应该是调用函数,指针指向

10. 判断字符串旋转

字符串旋转结果:
写一个函数,判断一个字符串是否为另外一个字符串旋转之后的字符串。
给定s1 =AABCD和s2 = BCDAA,返回1
给定s1=abcd和s2=ACBD,返回0.
例如:
AABCD左旋一个字符得到ABCDA
AABCD左旋两个字符得到BCDAA
AABCD右旋一个字符得到DAABC

在这里插入图片描述
这里讲一个新思路
在这里插入图片描述

2022-07-01-指针和数组运算

11. 同时判断升降序

描述
输入一个整数序列,判断是否是有序序列,
有序,指序列中的整数从小到大排序或者从大到小排序(相同元素也视为有序)。
数据范围: 3≤n≤50 序列中的值都满足 1≤val≤100
输入描述:
第一行输入一个整数N(3≤N≤50)。 第二行输入N个整数,用空格分隔N个整数。
输出描述:
输出为一行,如果序列有序输出sorted,否则输出unsorted。

【答案解析】
在这里插入图片描述

2022-07-08-简单

12. 找规律:箭形图案

在这里插入图片描述
在这里插入图片描述

#include <stdio.h>
int main()
{
    int n=0;
    while(scanf("%d",&n)==1)
    {
        int i=0,j=0;
        //控制行  上半部分
        for(i=0;i<n;i++)
        {
            //每一行

            //打印空格号
            for(j=0;j<n-i;j++)
            {
                printf("  ");
            }
            //打印*号
            for(j=0;j<=i;j++)
            {
                printf("*");
            }
            printf("\n");
        }
        //控制行 下半部分
        for(i=0;i<=n;i++)
        {
            //每一行
            //打印空格号
            for(j=0;j<i;j++)
            {
                printf("  ");
            }
            //打印*号
            for(j=0;j<=n-i;j++)
            {
                printf("*");
            }
            printf("\n");
        }
    }
    return 0;
}

13. flag 分组优化

在这里插入图片描述
【答案解析】

// 成绩是7个一组进行计算,当然可以用scanf 7个值进行求和,但是这样需要创建太多变量接收。
// 所以还是采用scanf 1个值,通过flag的判断进行分组
#include <stdio.h>
int main()
{
    int score = 0;
    // 成绩总和
    int all = 0;
    // flag == 7 划分1组
    int flag = 0;
    int max = 0;
    int min = 100;
    while (scanf("%d", &score) == 1)
    {
        if (score > max)
        {
            max = score;
        }
        if (score < min)
        {
            min = score;
        }
        all += score;
        // flag从1到7 共7个值
        flag++;
        if (flag == 7)
        {
            float s1 = (all - min - max) / 5.0;
            printf("%.2lf\n", s1);
            // 更改为初值
            flag = 0;
            all = 0;
            max = 0;
            min = 100;
        }
    }
    return 0;
}

2022-07-11-结构体大小计算

14. 结构体大小计算

在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;
};

【答案解析】
在这里插入图片描述

15. #define 定义宏(隐蔽)

有如下宏定义和结构定义

#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分配( )个字节的空间。

【答案解析】9个字节
说明:结构体向最长的char对齐,前两个位段元素一共4+2位,不足8位,合起来占1字节,最后一个单独1字节,一共3字节。另外,#define执行的是查找替换, sizeof(struct _Record_Struct) * MAX_SIZE这个语句其实是3*2+3,结果为9

16. 位段的使用

下面代码的结果是( )

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

在这里插入图片描述

17. 结构体内存对齐

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

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

A.16
B.9
C.12
D.8

【答案解析】C
在这里插入图片描述
这个题按照结构体内存对齐的方式计算就行

2022-07-12-枚举

18. 大小端与数组(重点)

在X86下,小端字节序存储,有下列程序

#include<stdio.h>
int main()
{
  union
  {
    short k;
    char i[2];
  }*s, a;
  s = &a;
  s->i[0] = 0x39;
  s->i[1] = 0x38;
  printf(%x\n”,a.k);
  return 0;
}

输出结果是( )
A.3839
B.3938
C.380039
D.不确定

【答案解析】A
在这里插入图片描述

2022-07-13-代码练习

19. 对异或、按位与的深刻理解

找单身狗
一个数组中只有两个数字是出现一次,其他所有数字都出现了两次。
编写一个函数找出这两个只出现一次的数字。

【答案解析】
找出一个只出现过一次的数字的问题处理方法就是找一个数字把里面所有的数字都异或一遍利用异或两次等于没异或的特点来处理。那么如果有两个数字都只出现了一次,那么如此得到的应该是两个数异或的结果。首先这个结果肯定不是0(要不然就全都配对了),所以里面一定至少一位是一。找出值为1的一位,以这一位的值将结果分为两组。例如1 2 3 4 1 2,异或完的结果应该是3^4得到的111,那么随便找一位就行了。例如找最低位,那么这一位是1的有1 3 1,是0的有2 4 2,由于是利用异或结果为1的某一位分的组,所以两个待查询数字一定分别在两组中。所以再找两个变量,分别异或两组数,即可找到这两个数。
在这里插入图片描述

20. 模拟实现atoi

在这里插入图片描述

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
//1. 空指针
//2. 空字符串
//3. 空格
//4. +-
//5. 越界
//6. 非数字字符
//
//
#include <ctype.h>
#include <limits.h>

enum Status
{
	VALID,
	INVALID
}sta = INVALID;//默认非法


int my_atoi(const char* str)
{
	// 判断正负号
	int flag = 1;
	// 先进行断言  1.空指针
	assert(str);
	if (*str == '\0')
		return 0;//非法0
	//跳过空白字符
	while (isspace(*str))
	{
		str++;
	}
	//+-
	if (*str == '+')
	{
		flag = 1;
		str++;
	}
	else if(*str == '-')
	{
		flag = -1;
		str++;
	}

	long long ret = 0;
	while (*str)
	{
		if (isdigit(*str))
		{
			//越界
			ret = ret * 10 + flag*(*str - '0');
			if (ret > INT_MAX || ret < INT_MIN)
			{
				return 0;
			}
		}
		else
		{
			return (int)ret;
		}
		str++;
	}
	if (*str == '\0')
	{
		sta = VALID;
	}
	return (int)ret;
}

int main()
{
	char arr[200] = "+1234";
	int ret = my_atoi(arr);
	if (sta == INVALID)
	{
		printf("非法返回:%d\n", ret);
	}
	else if (sta == VALID)
	{
		printf("合法转换:%d\n", ret);
	}

	return 0;
}

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

  • 6
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值