下面那个不是转义字符?
A.‘\n’
B.‘\060’
C.‘\q’
D.‘\b’
【答案解析】C
A:‘\n’ 转义字符,代表换行
B:‘\060’ 转义字符,060八进制数据,十进制为48,表示ASCII码为48的’0’
C:‘\q’ 什么都不是
D:‘\b’ 转义字符,表示退格
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”
【答案解析】B
即使是在支持C99标准的编译器下,变长数组无法进行初始化
用在switch语言中的关键字不包含哪个?( )
A.continue
B.break
C.default
D.case
【答案解析】A
continue是用来跳出本次循环的,而switch不是循环,因此其中不能使用continue关键字
下面哪个不是关键字:( )
A.int
B.struct
C.define
D.continue
【答案解析】
C语言关键字:C语言定义的,具有特定含义、专门用于特殊用途的C语言标识符,也称为保留字
define不是关键字,是编译器实现的,用来定义宏的预处理指令,不是C语言中的内容。int、struct和continue都是C语言中包含的关键字。
define不是关键字,是预处理指令
【答案解析】
出生日期的输入为8位,应考虑划分成年,月,日 分别输入
scanf("%4d%2d%2d", &year, &month, &date);//%4d就是读取4位整数
而不是直接%8d的形式导致后续无法分割
【答案解析】
计算体积的值时,4/3进行的是整型运算,所以要改成3.0
double v = (4.0/3)*pi*(r*r*r);
判断相等是两个=号,赋值是一个=号
%c是打印字符形式
从大到小输出
写代码将三个整数数按从大到小输出。
例如:
输入:2 3 1
输出:3 2 1
【答案解析】
这样显得代码很冗余
采用函数的方法进行变量的交换,当涉及到交换时传参就要采用传址的形式
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
最大公约数:即两个数据中公共约数的最大者。
求解的方式比较多,暴力穷举、辗转相除法、更相减损法、Stein算法算法
暴力穷举法:先找到两数当中最小的一个,不断减减,直到找到一个公共约数,使得两数同时除尽,算得公共约数
此处主要介绍:辗转相除法
思路:
例子: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中的内容即为两个数中的最大公约数。
第一次循环: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
用递归的方式实现阶乘
Fac设计成int 类型 每次递归调用都应该有返回值,main函数也应该用int来接收
#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可以
#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;
}
题目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
题目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)的结果是个随机值
#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阶的走法
#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]
的位置
代码执行结果
#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;
}
【答案解析】
逗号表达式的优先级最低(甚至低于赋值表达式),所以b的值是++c
获取一个整数二进制序列中所有的偶数位和奇数位,分别打印出二进制序列
【答案解析】
/*
思路:
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判断
写一个函数返回参数二进制中 1 的个数
【答案解析】
版本1:不断模2除2获取二进制每一位的1或0
n模2为1 则表示二进制位最后一位为1,count++,再除2,往前进一位,判断前一位是否为1
如果说只是淡出的判断正数是没有问题,但是如果是负数
例如:-1模2为-1,再除2就是0,退出循环 所以,应该让函数接收值为unsigned int类型
版本2:
但是接收为无符号类型时,-1会看做很大的正数,42亿多
版本3:
通过移位操作符实现
每次对最后一个二进制位进行判断(按位与1),不断向前移位
版本4:(思路++)
当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
方法1:
m,n 分别向前移位并按位与1,判断是否相等
方法2:
先对m,n 两数进行异或,相异为1,相同为0,再计算这个结果中存在几个1(用到了上述的ret&(ret-1))