C语言作业-Day5

写作能力有限,请多多包含( $ _ $ )
如有错误理解,请指出文中有误的地方。(可以私信)
一、选择题 
1、如下程序的功能是( )
#include <stdio.h>
int main()
{
  char ch[80] = "123abcdEFG*&";
  int j;
  puts(ch);
  for(j = 0; ch[j] != '\0'; j++)
    if(ch[j] >= 'A' && ch[j] <= 'Z')
       ch[j] = ch[j] + 'e' - 'E';
  puts(ch);
  return 0;
}

A: 测字符数组ch的长度                                B: 将数字字符串ch转换成十进制数

C: 将字符数组ch中的小写字母转换成大写    D: 将字符数组ch中的大写字母转换成小写

从for循环语句开始看,其意思是:初始化j=0;字符j 不为'\0'它就会遍历下去,所以for循环会将字符串ch给遍历一遍。接下来进入if条件判断语句,其判断条件是:j的范围在A~Z之间。进入if语句内部,一个字母对应的大写和小写之间的ASCII码值相差32(例如:a的ASCII码值为97,A的ASCII码值为65,),而且小写的大于大写的。所以题中'e'和'E'之间的ASCII码值相差 32(ch[j]+'e'-'E'相当于ch[j]+32)。一个字母从大写转化为小写就是在它自身上+32,小写转大写则是-32。

答案:D

2、对于代码段,下面描述正确的是( )

t=0;
while(printf("*"))
{
  t++;
  if (t<3)
     break;
}
A: 其中循环控制表达式与0等价          B: 其中循环控制表达式与'0'等价
C: 其中循环控制表达式是不合法的     D: 以上说法都不对
因print(“*”)函数调用的返回值是字符串中字符的个数,即为1。所以while后面的条件恒为真,循环进入死循环。如果有表达式可以实现循环控制表达式恒为真,那就等价于我们的循环控制表达式。所以循环控制表达式与'0'是等价的(字符'0'不是0)。

A:循环控制表达式与0等价,显然是错的,0恒为假,一次循环都不会进去更别说死循环了。

B:循环控制表达式与'0'等价,'0'的ASCII码值是48,循环控制表达式恒为真,循环进入死循环。

C选项是循环控制表达式不合法,一般来说,要出现循环控制表达式不合法,很可能是你的语法出错了,而题目中的死循环,虽然它死循环了,但循环是会进行的,所以是合法的,C错。

答案:B

 3、以下程序运行时,若输入 1abcedf2df<回车> 输出结果是( )

A: 1abcedf2df    B: 1ABCEDF2DF     C: 1AbCEdf2df     D: 1aBceDF2DF
#include <stdio.h>
int main()
{
  char ch;
  while ((ch = getchar()) != '\n')
  {
    if (ch % 2 != 0 && (ch >= 'a' && ch <= 'z'))
        ch = ch - 'a' + 'A';
    putchar(ch);
  }
  printf("\n");
  return 0;
}

语句①while ((ch = getchar()) != '\n'):通过getchar函数逐个记录输入字符,并且每个记录的字符都不是'\n'。

语句②if (ch % 2 != 0 && (ch >= 'a' && ch <= 'z')):判断条件是ch是小写字母,并且对应的ASCII码值不能被2整除。由此可知输入字符1abcedf2df<回车>中,a,c,e可以进入条件语句内部。

语句③ch = ch - 'a' + 'A';:其表示将小写字母转化为大写字母

1abcedf2df<回车>输入后    1,2不会进入语句②③,保留原样,a,c,e均被转化为大写字母,所以最后的结果为1AbCEdf2df,
程序首先考虑ch的ASCII码值是不是奇数,再看是不是小写字母,同时满足时被改为大写字母

答案:C

4 、下列条件语句中,功能与其他语句不同的是( )
A: if(a) printf("%d\n",x); else printf("%d\n",y);
B: if(a==0) printf("%d\n",y); else printf("%d\n",x);
C: if (a!=0) printf("%d\n",x); else printf("%d\n",y);
D: if(a==0) printf("%d\n",x); else printf("%d\n",y);

A选项,if语句中,若a!=0值时,打印x;当a=0时,打印y

B选项,当a=0时,打印y,当a!=0打印x。

C选项,当a!=0时,打印x;a=0时打印y

D选项,当a=0时,打印x,a!=时打印y。

答案:D

5、我们知道C语言的 break 语句只能跳出离它最近的一层循环,可是有时候我们需要跳出多层循环,下列跳出多层循环的做法正确的是【多选】( )
A: 将程序写成函数用return结束函数,便可跳出循环
B: 修改外层循环条件例如
for (int i = 0; i < MAX1; i++)
{
	for (int j = 0; j < MAX2; j++)
	{
		if (condition)
		{
			i = MAX1;//1
			break;//2
		}
	}
 //3
}

        当condition满足的时候,i=MAX1,然后break,break跳出一层循环,跳到3的位置,继续走发现没有代码执行了,跳到开始的条件判断,发现不满足i<MAX1这个条件,故循环结束。可以看出,当condition满足时,直接跳出这个多层循环,故B正确

C. 在外层循环设置判断条件例如

for (; symbol != 1 && condition2; )
{
    for (; symbol != 1 && condition3; )
    {
        if (condition1)
            symbol = 1;
    }
}

        C:当condition满足时,symbol被赋值为1。可以看出,两层循环进行的条件均是symbol!=1,也就是说, 当symbol不等于1时两层循环才会有进行的可能,所以当symbol为1时,两层循环都会被跳出,C正确

D. 在外层循环后面加入break例如

for ( ;symbol; )
{
    for ( ;symbol!=1; )
    {
        if (condition)
            symbol = 1;//1
    }
    if (symbol == 1)//2
        break;
}

        D:当condition满足时,symbol等于1,会跳到2的位置。symbol等于1,满足if(symbol==1),故跳出循环,D正确。

答案:ABCD

二、编程题
1、数字在升序数组中出现的次数_牛客题霸_牛客网 (nowcoder.com)

/**
 * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
 *
 *
 * @param nums int整型一维数组
 * @param numsLen int nums数组长度
 * @param k int整型
 * @return int整型
 */
int GetNumberOfK(int* nums, int numsLen, int k ) {
    int i = 0;
    int count = 0;
    for (i = 0; i < numsLen; i++)
        //遍历一遍数组
    {
        if (nums[i] == k)
            //k是目标,当等于时计数器+1
        {
            count++;
        }
    }
    return count;//返回统计结果
}
采用遍历也能搞定,不过数组为非降序,采用二分查找的思想最优,先二分找到最左边的数字位置,再二分查找最 右边的数字位置,两个位置相减+1 就是长度了。
中间比找的值大:则要找的数字肯定在右边, left = mid + 1;
中间比找的值小:则要找的数字肯定在左边, right = mid - 1
中间值与找的值相同:
找的最左边数字:如果 mid 就是 left ,则返回 mid 就行,否则重置 right=mid-1 ,把中心不断向左偏移
找的最右边数字:如果 mid 就是 right ,则返回 mid 就行,否则重置 left=mid+1 ,把中心不断向右偏移
int two_search(int* data, int len, int k, int flag) //flag:0-找左边, 1-找右边
{
	int left = 0, right = len - 1, mid;
	while (left <= right)
    {
		mid = left + (right - left) / 2;
		if (data[mid] > k)
			right = mid - 1;
		else if (data[mid] < k)
			left = mid + 1;
		else 
            {
			if (flag == 0) {//flag==0时,找最左边的数字
				if (mid == left || data[mid - 1] != k) return mid;
				else right = mid - 1;//把中心向左推
			}
			else 
            {//flag==1时,找最右边的数字
				if (mid == right || data[mid + 1] != k) return mid;
				else left = mid + 1;//把中心向右推
			}
		}
	} return -1;
} 
int GetNumberOfK(int* data, int dataLen, int k) 
{
	if (dataLen == 0) return 0;
	int left = two_search(data, dataLen, k, 0);
	int right = two_search(data, dataLen, k, 1);
	if (left == -1 && right == -1) return 0; //表示没有找到k这个数据
	return right - left + 1;
}
2、面试题 05.06. 整数转换 - 力扣(LeetCode)
int convertInteger(int A, int B){
    //位运算,先异或(相同为0,相异为1)
    //再利用0的二进制进行与运算(遇1为1)
    int c = A ^ B;//两数异或后的值
    int i = 0;//循环控制器
    int count = 0;//计数器
    for(i = 0 ;i < 32 ;i++)
    {
        if(c & 1 == 1)//利用与1的 按位与运算,发现一个1,计数器就++
        {
            count++;
        }
        c >>= 1;// c 变量的二进制位往右移动一位 
    }
    return count;//返回计数器的值
}

 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值