【C语言初阶】12 习题①

2022-4-1-字符串

1. 转义字符的判断

下面那个不是转义字符?
A.‘\n’
B.‘\060’
C.‘\q’
D.‘\b’

【答案解析】C
A:‘\n’ 转义字符,代表换行
B:‘\060’ 转义字符,060八进制数据,十进制为48,表示ASCII码为48的’0’
C:‘\q’ 什么都不是
D:‘\b’ 转义字符,表示退格

2. 变长数组概念

C语言中下面哪个数组的创建错误的:( )
A.int arr[10] = {0}
B.int n = 10; int arr[n] ={0}
C.int arr[] ={1,2,3,4,5,6,7,8,9,0}
D.char ch[10] = “hello bit”

【C语言初阶】12 习题①_第1张图片
【答案解析】B
即使是在支持C99标准的编译器下,变长数组无法进行初始化

2022-4-8-关键字

3. switch语句中的关键字

用在switch语言中的关键字不包含哪个?( )
A.continue
B.break
C.default
D.case

【答案解析】A
continue是用来跳出本次循环的,而switch不是循环,因此其中不能使用continue关键字

4. 关键字

下面哪个不是关键字:( )
A.int
B.struct
C.define
D.continue

【答案解析】
C语言关键字:C语言定义的,具有特定含义、专门用于特殊用途的C语言标识符,也称为保留字
define不是关键字,是编译器实现的,用来定义宏的预处理指令,不是C语言中的内容。int、struct和continue都是C语言中包含的关键字。
define不是关键字,是预处理指令

5. 划分思想

【C语言初阶】12 习题①_第2张图片
【答案解析】
出生日期的输入为8位,应考虑划分成年,月,日 分别输入

scanf("%4d%2d%2d", &year, &month, &date);//%4d就是读取4位整数

而不是直接%8d的形式导致后续无法分割

2022-4-10-指针大小

6. 除法运算的规律

【C语言初阶】12 习题①_第3张图片
【答案解析】
计算体积的值时,4/3进行的是整型运算,所以要改成3.0

double v = (4.0/3)*pi*(r*r*r);

2022-4-12-if语句

7. 注意事项

判断相等是两个=号,赋值是一个=号
%c是打印字符形式

8. 函数解决冗余问题

从大到小输出
写代码将三个整数数按从大到小输出。
例如:
输入:2 3 1
输出:3 2 1

【答案解析】
【C语言初阶】12 习题①_第4张图片
这样显得代码很冗余
【C语言初阶】12 习题①_第5张图片
采用函数的方法进行变量的交换,当涉及到交换时传参就要采用传址的形式

9. switch case 语句

int func(int a)
{
    int b;
    switch (a)
    {
        case 1: b = 30;
        case 2: b = 20;
        case 3: b = 16;
        default: b = 0;
    }
    return b;
}

则func(1) = ( )
A.30
B.20
C.16
D.0

switch的每个case之后如果没有加break语句,当前case执行结束后,会继续执行紧跟case中的语句。func(1)可知,在调用func时形参a的值为1,switch(a)<==>switch(1),case 1被命中,因为该switch语句中所有分支下都没有增加break语句,因此会从上往下顺序执行,最后执行default中语句返回。因此:选择D

10. 辗转相除法(求最大公约数)

最大公约数:即两个数据中公共约数的最大者。
求解的方式比较多,暴力穷举、辗转相除法、更相减损法、Stein算法算法
暴力穷举法:先找到两数当中最小的一个,不断减减,直到找到一个公共约数,使得两数同时除尽,算得公共约数
【C语言初阶】12 习题①_第6张图片
此处主要介绍:辗转相除法
思路:
例子:18和24的最大公约数
第一次:a = 18 b = 24 c = a%b = 18%24 = 18
循环中:a = 24 b=18
第二次:a = 24 b = 18 c = a%b = 24%18 = 6
循环中:a = 18 b = 6
第三次:a = 18 b = 6 c=a%b = 18%6 = 0
循环结束
a b ----> c
18%24 18
24%18 6
18% 6 0
此时b中的内容即为两个数中的最大公约数。
【C语言初阶】12 习题①_第7张图片

2022-4-15-for循环

11. 循环判断结束

判断程序的输出结果
【C语言初阶】12 习题①_第8张图片

第一次循环:a = 1,b=1—>b小于20,if不成立,b%3==1%3==1成立,b=b+3, 此时b的值为4
第一次循环:a = 2,b=4—>b小于20,if不成立,b%3==4%3==1成立,b=b+3, 此时b的值为7
第一次循环:a = 3,b=7—>b小于20,if不成立,b%3==7%3==1成立,b=b+3, 此时b的值为10
第一次循环:a = 4,b=10—>b小于20,if不成立,b%3==10%3==1成立,b=b+3, 此时b的值为13
第一次循环:a = 5,b=13—>b小于20,if不成立,b%3==13%3==1成立,b=b+3, 此时b的值为16
第一次循环:a = 6,b=16—>b小于20,if不成立,b%3==16%3==1成立,b=b+3, 此时b的值为19
第一次循环:a = 7,b=19—>b小于20,if不成立,b%3==19%3==1成立,b=b+3, 此时b的值为22
第一次循环:a = 8,b=22—>b大于20,if成立,循环break提出
最后打印a:8

当b的值为22时,a进行++,再进行的判断,所以a=8

2022-4-19-函数传参

12. 打印素数的优化

打印100~200之间的素数
【C语言初阶】12 习题①_第9张图片

2022-4-22-函数递归

13. 递归求阶乘

用递归的方式实现阶乘

【C语言初阶】12 习题①_第10张图片
Fac设计成int 类型 每次递归调用都应该有返回值,main函数也应该用int来接收

14. reverse 逆置字符串(重点)

14.1 循环的方式实现

#include 
#include
//  1.循环的方式
int main()
{
	char arr[] = "abcdefg";
	int length = strlen(arr);
	int left = 0;
	int right = length - 1;
	while (left < right)
	{
		int tmp = arr[left];
		arr[left] = arr[right];
		arr[right] = tmp;
		left++;
		right--;
	}
	printf("%s", arr);
	return 0;
}

通过left ,right下标指定所要交换的元素,两两交换
这里提一下sizeof函数和strlen函数的区别
sizeof计算的字符个数,strlen计算的是字符串长度
在计算字符串时,sizeof会包括’ \0 '一同计算,所以计算出来比strlen多1个字符
而且sizeof不能在传递数组的函数内部进行计算:因为传递过来的数组是首元素地址,地址就是4/8字节 但strlen可以

14.2 递归的方式实现(1个参数)(重点)

【C语言初阶】12 习题①_第11张图片

#include 
//题目中不允许使用库函数,所以采用my_strlen
int my_strlen(char* str)
{
	int count = 0;
	while (*str != '\0')
	{
		count++;
		str++;
	}
	return count;
}
void reverse(char* str)
{
	//1 .将要a元素放在tmp临时变量当中
	char tmp = *str;
	int  length = my_strlen(str);
	//2 .将g元素放到a的位置
	*str = str[length - 1];
	//3. 将g的位置用\0替代,后续逆置是通过斜杠0判断所需要逆置的元素个数,所以1组交换完成就要用\0替换
	str[length - 1] = '\0';
	// str指针+1  判断是否还需要逆置(逆置个数)
	if (my_strlen(str + 1) >= 2)
	{
		//4.递归
		reverse(str + 1);
	}
	//5. 将a放到g的位置
	str[length - 1] = tmp;
}
int main()
{
	char arr[] = "abcdefg";
	reverse(arr);
	printf("%s", arr);
	return 0;
}

2022-04-24-数组的定义和初始化

15. strlen和sizeof的区别

题目1:下面代码的结果是:( )

#include 
int main()
{
    char str[] = "hello bit";
    printf("%d %d\n", sizeof(str), strlen(str));
	return 0;
}

A.10 9
B.9 9
C.10 10
D.9 10

【答案解析】
【C语言初阶】12 习题①_第12张图片

题目2: 给出以下定义:

char acX[] = “abcdefg”;
char acY[] = {‘a’,’b’,’c’,’d’,’e’,’f’,’g’};

以下说法正确的是( )
A.数组acX和数组acY等价
B.数组acX和数组acY的长度相同
C.sizeof(acX)>sizeof (acY)
D.strlen (acX)>strlen (acY)

【答案解析】C
acX和acY都是字符数组,但是初始化表达式不同,acX和acY的区别如下:
acX:数组中总共有8个元素,分别是:‘a’,‘b’,‘c’,‘d’,‘e’,‘f’,‘g’,‘\0’
acY:数组中总共有7个元素,分别是:‘a’,‘b’,‘c’,‘d’,‘e’,‘f’,‘g’
sizeof求的是有效元素个数
strlen求的是字符串长度,从首元素开始计算,遇见‘\0’停止,由于acY数组没有’\0‘,所以strlen(acY)的结果是个随机值

2022-04-27-简单

16. 跳台阶(菲波那切数列)(重点)

【C语言初阶】12 习题①_第13张图片
【答案解析】

#include 
int fib(int n)
{
    if(n<=2)
        return n;
    else
        return fib(n-1)+fib(n-2);
}
int main()
{
    int n = 0;
    scanf("%d", &n);
    printf("%d\n", fib(n));
    return 0;
}

fib函数代表的是有多少种走法
假如fib(10)
小乐乐走一步的话 ,还剩9阶 fib(9)9阶的走法
小乐乐走两步的话 ,还剩8阶 fib(8)8阶的走法

17. 对一个数组同时赋i,j下标

【C语言初阶】12 习题①_第14张图片
【答案解析】

#include 
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【i】中元素是否与del相等,若相等不赋值
            arr[j++] = arr[i];//等价于 arr[j]=arr[i],j++ 
        }
    }
    for(i=0; i<j; i++)//j中就是删除过后的元素
    {
        printf("%d ", arr[i]);    
    }
    return 0;
}

在一个数组中同时赋值 i j 下标,若arr[i]与要删除的元素不同则赋值到arr[j]的位置

2022-05-08-操作符的使用

18. 逗号表达式的优先级(重点)

代码执行结果

#include 
int main()
{
	int a, b, c;
	a = 5;
	c = ++a;
	b = ++c, c++, ++a, a++;
	b += a++ + c;
	printf("a = %d b = %d c = %d\n:", a, b, c);
	return 0;
}

【答案解析】
【C语言初阶】12 习题①_第15张图片
逗号表达式的优先级最低(甚至低于赋值表达式),所以b的值是++c

19. 打印整数二进制的奇数位和偶数位

获取一个整数二进制序列中所有的偶数位和奇数位,分别打印出二进制序列

【答案解析】

/*
思路:
1. 提取所有的奇数位,如果该位是1,输出1,是0则输出0
2. 以同样的方式提取偶数位置
 检测num中某一位是0还是1的方式:
   1. 将num向右移动i位
   2. 将移完位之后的结果与1按位与,如果:
      结果是0,则第i个比特位是0
      结果是非0,则第i个比特位是1
*/
void Printbit(int num)
{
	for(int i=31; i>=1; i-=2)
	{
		printf("%d ", (num>>i)&1);
	}
	printf("\n");
    
	for(int i=30; i>=0; i-=2)
	{
		printf("%d ", (num>>i)&1);
	}
	printf("\n");
}

将num进行右移,再按位与跟1判断

20. 二进制中1的个数(重点)

写一个函数返回参数二进制中 1 的个数

【答案解析】
版本1:不断模2除2获取二进制每一位的1或0
【C语言初阶】12 习题①_第16张图片
【C语言初阶】12 习题①_第17张图片
n模2为1 则表示二进制位最后一位为1,count++,再除2,往前进一位,判断前一位是否为1
如果说只是淡出的判断正数是没有问题,但是如果是负数
例如:-1模2为-1,再除2就是0,退出循环 所以,应该让函数接收值为unsigned int类型

版本2:
【C语言初阶】12 习题①_第18张图片
但是接收为无符号类型时,-1会看做很大的正数,42亿多

版本3:
通过移位操作符实现
【C语言初阶】12 习题①_第19张图片
每次对最后一个二进制位进行判断(按位与1),不断向前移位

版本4:(思路++)
【C语言初阶】12 习题①_第20张图片
当n=15时,1111按位与上1110 变成1110 将最后1位的1拿走了
1110 按位与 1101 变成1100 将第二位的1拿走了

每按位与一次n-1 就拿走1个靠后的1
当n=0循环结束

拓展

如何判断1个数是不是2的n次方

//2^1
//10
//2^2
//100
//2^3
//1000

也可以采用0 == n & (n - 1)的方式,拿掉最前面的1
【C语言初阶】12 习题①_第21张图片

21. 求两个数二进制中不同位的个数(重点)

方法1:
【C语言初阶】12 习题①_第22张图片
m,n 分别向前移位并按位与1,判断是否相等
方法2:
【C语言初阶】12 习题①_第23张图片
先对m,n 两数进行异或,相异为1,相同为0,再计算这个结果中存在几个1(用到了上述的ret&(ret-1))

【C语言初阶】12 习题①_第24张图片

你可能感兴趣的:(刷题日记,c语言)