前言:截止现在,我们C语言的大部分基础内容就已经讲完了,但是,光掌握基础只是还是不够的,所以小编会将自己写过的一些题整理起来,不定期更新刷题博客,希望能扩展大家的思路。
话不多说,现在就开始我们这一节的刷题博客吧!!
选择题
题目1
请阅读以下程序,其运行结果是( )
int main()
{
char c='A';
if('0'<=c<='9')
printf("YES");
else
printf("NO");
return 0;
}
A: YES B: NO C: YESNO D: 语句错误
解释:'0'<=c<='9'并非判断x大于等于字符0,小于等于字符9,而是先执行'0'<=c,使用这个表达式的结果再和'9'比较,'0'的ASCII码值是48,'A'的ASCII码值是'65',故'0'<c是真值1,1无疑是小于字符'9'的,最终是真
所以答案是A
题目2
假设编译器规定 int 和 short 类型长度分别为32位和16位,若有下列C语言语句,则 y 的机器数为()
unsigned short x = 65530;
unsigned int y = x;
A: 0000 7FFA B: 0000 FFFA C: FFFF 7FFA D: FFFF FFFA
解释:变量x在计算机中存储的是:1111 1111 1111 1010,十六进制表示为0XFFFA
x给y赋值时会整型提升,而无符号数在提升时高位补0,其实就相当于把x的值放在了y的低2个字节的空间中,故选B
题目3
下列程序的输出结果是什么( )
#include<stdio.h>
int main()
{
int n = 1001;
int ans = 0;
for(int i = 1; i <= n; ++i)
{
ans ^= i % 3;
}
printf("%d",ans);
return 0;
}
A: -2 B: 0 C: 1 D: 2
解释:i % 3 的值按1、2、0循环,从i=1到i=999,一共有i%3经历了333组1,2,0的循环,当i=1000时,i%3==1,当i=1001时,i%3=2,所以ans将会与334个1进行按位与,333个0进行按位与,334个2进行按位与。我们之前就说过,对于任何数a,a^a=0,a^0=a,所以偶数个a互相按位与,最终的结果会变成0,奇数个a按位与,最终的结果还是a。
所以上述的结果是0
所以选B
题目4
要使 a 的低四位翻转,需要进行操作是( )
A: a|0xF B: a&0xF C: a^0xF D: ~a
解释:将a的第四位进行翻转,意思是将0变成1,将1变成0,要将低四位进行翻转,同时其他位保持不变,可以与0XF进行异或,这样以来,除了低四位之外的其他位是分别与0相异或的,如果原来的位置是0,那异或后的结果还是0,如果原来位的结果是1,那异或之后的结果还是1;而对于低四位,原来位如果是1,异或之后就会变成0,原来是0,异或之后就变成了1,实现了低四位的翻转。
所以答案选C
编程题
题目1:数字颠倒_牛客题霸_牛客网
思路1:这道题的关键就是要将整数转换为字符串,剩下的就都好办了。我们应该如何将整数转为字符串呢。大家有没有想到文件操作中的sprintf函数,它是将格式化的数据写入到字符串中的函数,那这道题就十分好办了。直接创建一个字符数组,然后将格式化的数据写入到字符数组中,最后再将字符串中的字符逆置即可
思路2:上面我们是直接将整数转换为字符串来完成题目的,有没有什么办法能够不经过字符串这一转变直接打印整数的每一位呢?当然是有的了,之前我们在强化训练中反复利用模除10得到一个数的个位,整除10去掉一个数的个位,这不就能帮助我们顺利完成这一道题吗
思路1:
#include <stdio.h>
#include<string.h>
int main()
{
int n=0;
scanf("%d",&n);
//利用sprintf,将格式化的数据写入到字符串中
char ch[11];
sprintf(ch,"%d",n);
size_t sz=strlen(ch);
int left=0,right=sz-1;
while(left<=right)
{
char tmp=ch[left];
ch[left]=ch[right];
ch[right]=tmp;
left++;
right--;
}
printf("%s",ch);
return 0;
}
思路2:
#include<stdio.h>
int main()
{
int n;
scanf("%d",&n);
if(n==0){
printf("%d",n);
}
while(n)
{
int m=n%10;
printf("%d",m);
n/=10;
}
return 0;
}
题目2:单词倒排_牛客题霸_牛客网
思路1:我们先读懂题目要求,就是要从后往前打印所给字符串中的单词:先打印所给字符串中最后一个单词,再打印倒数第二个......
那这道题的关键就在于如何找到最后一个单词的首字母了,我们可以先找到字符串的末尾(\0之前的那个位置),然后定义一个变量p1,对字符串开始从后往前遍历,字符串的末尾可能是非字母字符,那我们就要跳过所有的非字母字符,当我们跳过所有的非字母字符以后,此时p1指向的就是最后一个单词的末尾,然后保存一下这个末尾位置,记为p2。我们要如何找到最后一个单词的首字母?自然是让p1继续往前遍历,直到遇到非字母字符,此时p1的下一个位置就是最后一个单词的首字母,然后我们就可以根据p1和p2的范围得到最后一个单词所有字母的下标范围,这样就可以遍历打印最后一个字母。对于字符串中其他单词的打印也是采用相同的方法。
思路2:我们可以把字符串中的非字母字符看成分隔符,定义一个字符指针数组,用于保存每个单词的起始字符地址,接下来将非字母字符全部替换成为字符串结尾标志'\0',则单词字符字母遇到结尾就结束了,相当于把一个字符串以非字母字符进行切割成为了多个字符串,最终对字符指针数组进行逆序打印每个单词即可
思路1:
#include<string.h>
#include<stdio.h>
#include<ctype.h>
int main()
{
char ch[10000];
fgets(ch,10000,stdin);
int sz=strlen(ch);
if(ch[sz-1]=='\n')
{
ch[sz-1]='\0';
sz--;
}
int p1=sz-1;
while(p1>=0)
{
//先跳过所有非字母字符
while(p1>=0&&!isalpha(ch[p1]))
{
p1--;
}
//此时p1指向的就是单词的最后一个字母,现在我们要将这个单词打印出来
int p2=p1;
while(p1>=0&&isalpha(ch[p1]))
{
p1--;
}
//此时p1的后一个位置就是单词的开头
for(int i=p1+1;i<=p2;i++)
{
printf("%c",ch[i]);
}
printf(" ");
}
return 0;
}
思路2:
#include <ctype.h>
#include<stdio.h>
#include<string.h>
int main() {
//读取字符串
char ch[10000];
fgets(ch, 10000, stdin);
int sz = strlen(ch);
if (ch[sz - 1] == '\n') {
ch[sz - 1] = '\0';
sz--;
}
char* word[10000]={NULL};//word是字符指针数组,数组中的元素指向字符串中每个独立单词的首字母
int size=0;
char*p=ch;
while(*p)
{
//如果p指向的字符是字母字符,那么就将这个字符的地址存储到word数组中
if(isalpha(*p))
{
word[size++]=p;
//跳过这个字母中的其他字符
p++;
while(*p&&isalpha(*p))
{
p++;
}
//走到这里,p指向的就不是字母字符了
}
*p='\0';
p++;
}
for(int i=size-1;i>=0;i--)
{
printf("%s",word[i]);
printf(" ");
}
return 0;
}