C语言强化训练(1)

前言:截止现在,我们C语言的大部分基础内容就已经讲完了,但是,光掌握基础只是还是不够的,所以小编会将自己写过的一些题整理起来,不定期更新刷题博客,希望能扩展大家的思路。

话不多说,现在就开始我们的第一篇刷题博客吧!!

选择题

题目一

1.下面关于C语言的编译和链接说法错误的是?

A.C语言是一门编译型计算机语言

B.写出来的C语言代码直接就可以运行的

C.C语言代码需要经过编译和链接生成可执行程序才能运行的

D.C语言代码经过编译生成目标文件,目标文件和链接库通过链接生成可执行程序

解答 :C语言是一门编译型计算机语言,代码需要经过编译和链接生成可执行程序才能运行的,C语言代码经过编译生成目标文件,目标文件和链接库通过链接生成可执行程序。

所以选B

题目二

下面那个不是转义字符?

A.'\n'

B.'\060'

C.'\q'

D.'\b'

解答:A:'\n' 转义字符,代表换行

B:'\060' 转义字符,060八进制数据,十进制为48,表示ASCII码为48的'0'

(注意:\ddd:d d d表示1~3个八进制的数字,如:\130表示字符X

\xdd:d d表示2个十六进制的数字,如,\x30表示字符0

C:'\q' 什么都不是

D:'\b' 转义字符,表示退格

题目三

下面程序的结果是:( )

复制代码
#include <stdio.h>
#include <string.h>
int main()
{
    printf("%d\n", strlen("c:\test\121"));
    return 0;
}

A.7

B.8

C.9

D.10

解答:strlen是用于求字符串中'\0'之前的字符串的长度的函数,对于字符串"c:\test\121",我们只需要注意用\修饰后的转义字符,这个字符串是由以下字符组成的:'c' ':' '\t' 'e' 's' 't' '\121' '\0' ,所以'\0'之前的字符个数为7,所以选A

题目四

关于C语言变量说法错误的是?

A.变量是用来描述生活中经常发生变化的值

B.变量可以分为局部变量和全局变量

C.局部变量是放在内存的静态区的,全局变量是放在内存的栈区

D.当全局变量和局部变量名字相同的情况,且都可以使用的时候,局部变量优先

解答:局部变量是放在内存的栈区的,全局变量是放在内存的静态区,所以选c

题目五

关于C语言算术操作符说法正确的是?

A.除号两边都是小数才能执行小数除法

B.%操作符的操作数可以是整数,也可以是小数

C.%操作符计算的结果是两个操作数整除之后的商

D.负数求模的规则是,结果的正负号由第一个运算数的正负号决定。

解答

A:除号两边只要有一个是小数,就执行小数除法

B:%操作符的操作数只能是整数

C:%操作符计算的结果是两个操作数整除之后的余数

题目六

以下不正确的定义语句是( )

A: double x[5] = {2.0, 4.0, 6.0, 8.0, 10.0};

B: char c2[] = {'\x10', '\xa', '\8'};

C: char c1[] = {'1','2','3','4','5'};

D: int y[5+3]={0, 1, 3, 5, 7, 9}

解答:本题考查转义字符:

\xdd:d d表示2个十六进制的数字,'\xa'中的a是十六进制中的10,是一个转义字符,但是**\ddd**:d d d表示1~3个八进制的数字,而8不是8进制数字,所以选择B

题目七

test.c 文件中包括如下语句,文件中定义的四个变量中,是指针类型的变量为【多选】( )

复制代码
# define INT_PTR int* 
typedef int* int_ptr; 
INT_PTR a, b;
int_ptr c, d;

A: a B: b C: c D: d

解答:#define宏定义实现的是替换机制,而typedef是给关键字进行重命名,变量c,d的类型都是int_ptr,即int*,所以c,d都是指针变量对于a,b两个变量,我们直接对INT_PTR进行替换,即int*a,b,所以a的类型是int*,b的类型为int

所以结果选A C D

题目八

若给定条件表达式 (M)?(a++):(a--) ,则其中表达式 M ( )

A: 和(M==0)等价 B: 和(M==1)等价 C: 和(M!=0)等价 D: 和(M!=1)等价

解答

(表达式1)? (表达式2): (表达式3)为三目运算符。

计算规则为:先判断表达式1是否为真,若为真,则计算表达式2,并将表达式2的结果作为整个表达式最终的结果,表达式3不计算;否则,表达式3的结果为最终结果,表达式2不计算。 所以表达式M等价于表达式M为真,C语言中规定,非0表达式都为真,所以选C

题目九

有如下定义语句,则正确的输入语句是( )

复制代码
int b;
char c[10];

A: scanf("%d%s",&b,&c); B: scanf("%d%s",&b,c); C: scanf("%d%s",b,c); D: scanf("%d%s",b,&c);

解答

这道题的答案可能小伙伴们一眼就能看出来选B,这是正确的,但我们现在主要来讲解一下A选项,我们需要注意的是,A选项的写法在某些情况下也可以完成任务,这是因为c&c内存地址值相同 (都指向数组开头),但是它们的类型不同

  • c 的类型是 char*(指向字符的指针)

  • &c 的类型是 char (*)[10](指向包含10个字符的数组的指针)

在大多数系统上,这些地址值相同,所以可能选项A看似工作,但:

  1. 违反C标准(类型不匹配)

  2. 可能在某些严格的编译器上警告或错误

  3. 是糟糕的编程实践

如果这道题是多选,我们可以考虑将A纳入选择范围

题目十

下面代码的结果是?

复制代码
#include <stdio.h>
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;
}

解答

++运算符:分为前置++和后置++,

前置++:先加1,后使用,即先使用变量中内容,然后给结果加1

后置++:先使用变量中内容,整个表达式结束时,给变量加1

复制代码
#include <stdio.h>
int main()
{
	int a, b, c;
	a = 5;
	c = ++a;// ++a:加给a+1,结果为6,用加完之后的结果给c赋值,因此:a = 6  c = 6
	b = ++c, c++, ++a, a++;
   // 这里先算b=++c, b得到的是++c后的结果,b是7
   // b=++c 和后边的整体构成逗号表达式,依次从左向右计算的。
   // 表达式结束时,c++和,++a,a++会给a+2,给c加1,此时c:8,a:8,b:7
	b += a++ + c; // a先和c加,结果为16,在加上b的值7,比的结果为23,最后给a加1,a的值为9
	printf("a = %d b = %d c = %d\n:", a, b, c); // a:9, b:23, c:8
	return 0;
}

题目十一

关于scanf函数说法正确的是?

A.scanf中也有占位符,占位符和后边的参数提供的地址一一对应。

B.scanf()处理所有占位符时,会自动过滤起首的空白字符,包括空格、制表符、换行符

C.scanf的占位符%s表示读取一个字符串,遇到空白字符也全部读取

D.scanf是库函数,库函数不需要包含头文件

解答:A正确

B:scanf()处理数值占位符时,会自动过滤空白字符,包括空格、制表符、换行符,scanf输出字符占位符的时候,不忽略空白字符,总是返回当前第一个字符,无论该字符是否为空格。

C:scanf的占位符%s表示读取一个字符串,遇到空白字符就停止读取。

D:scanf需要包含stdio.h这个头文件的

编程题

打印从1到最大的n位数_牛客题霸_牛客网

描述

输入数字 n,按顺序打印出从 1 到最大的 n 位十进制数。比如输入 3,则打印出 1、2、3 一直到最大的 3 位数 999。

  1. 用返回一个整数列表来代替打印

  2. n 为正整数,0 < n <= 5

解答1:这道题的关键就是求出最大的n位数,比如给定的整数是5,那么我们就要得到99999,这个数应该如何得到?

可以把它拆解成:9+9*10+9*100+9*1000+9*10000,这个式子中9是不变的,变的是10的次方数,那我们就只需循环产生10的次方数即可

解答2:上面那个我们是将最大的n位数拆分成好几个加数得到的,其实还有一个更简单的方法,,比如我们要求最大的5位数99999,他可以由10^5-1得到

思路1:

复制代码
 #include<math.h>
#include <stdlib.h>
int* printNumbers(int n, int* returnSize ) 
{
    // write code here
    int m=n;
    int ret=0;
    while(m--)
    {
        //产生10的次方数
        int x=(int)pow(10,m);
        int y=x*9;
        ret+=y;
    }
    *returnSize=ret;
    int*nums=(int*)malloc(sizeof(int)*ret);
    for(int i=0;i<ret;i++)
    {
        nums[i]=i+1;
    }
    return nums;
}

思路二:

复制代码
int* printNumbers(int n, int* returnSize) 
{
	*returnSize = pow(10, n) - 1; //确定最大的数字
	int* arr = (int*)malloc(sizeof(int) * (*returnSize));//申请足够大小的空间
	for (int i = 0; i < *returnSize; i++)
	{
		arr[i] = i + 1;//下标从0开始,而数值从1开始
	} 
		return arr;
}

计算日期到天数转换_牛客题霸_牛客网

描述

每一年中都有 1212 个月份。其中,1,3,5,7,8,10,121,3,5,7,8,10,12 月每个月有 3131 天;4,6,9,114,6,9,11 月每个月有 3030 天;而对于 22 月,++闰年++ 时有 2929 天,平年时有 2828 天。

现在,对应输入的日期,计算这是这一年的第几天。

一个年份是++闰年++ 当且仅当它满足下列两种情况其中的一种:

这个年份是 4 的整数倍,但不是 100 的整数倍;

这个年份是 400 的整数倍。

解答

这道题只需要将每个月的天数枚举出来,然后根据当前月份向前累加满月的天数,然后再加上当前月所在的天数。最终考虑平闰年的 2 月份区别是否增加一天

复制代码
#include <stdio.h>

int GetDayOfMonth(int year,int month)
{
    int arr[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};
    if(month==2&&((year%4==0&&year%100!=0)||(year%400==0)))
    {
        arr[month]++;
    }
    return arr[month];
}

int main() 
{
   int year,month,day;
   scanf("%d%d%d",&year,&month,&day);
   int sum=day;
    for(int i=1;i<month;i++)
    {
        sum+=GetDayOfMonth( year,  i);
    }
    printf("%d",sum);

    return 0;
}
相关推荐
地平线开发者2 小时前
理想汽车智驾方案介绍专题 3 MoE+Sparse Attention 高效结构解析
人工智能·算法·自动驾驶
nece0012 小时前
PHP单独使用phinx使用数据库迁移
开发语言·php·数据库迁移·phinx
mmz12075 小时前
动态规划2(c++)
开发语言·c++
一支鱼6 小时前
leetcode-2-两数相加
算法·leetcode·typescript
接着奏乐接着舞。7 小时前
前端RSA加密遇到Java后端解密失败的问题解决
java·开发语言·前端
冷风沐雨7 小时前
LVGL移植(STM32)
c语言·stm32·单片机
斯坦索尼7 小时前
关于 01 背包问题的简单解释,理解状态转移与继承的相似性
算法·01背包问题
学涯乐码堂主8 小时前
《信息学奥林匹克辞典》中的一个谬误
数据结构·c++·算法·青少年编程·排序算法·信奥·gesp 考试
柯南二号8 小时前
【Java后端】SpringBoot配置多个环境(开发、测试、生产)
java·开发语言·spring boot