seo网站推广公司,网站开发从入门到精通,江阴做网站公司,如何建立网站域名文章目录 C语言常考及易错题整理选择题全局、局部和静态变量#define与typedef转义字符操作符循环其他 编程题计算日期到天数转换柯尼希定理旋转数组的最小数字描述错误的集合整数转换密码检查 C语言常考及易错题整理
选择题
全局、局部和静态变量
执行下面程序#xff0c;正… 文章目录 C语言常考及易错题整理选择题全局、局部和静态变量#define与typedef转义字符操作符循环其他 编程题计算日期到天数转换柯尼希定理旋转数组的最小数字描述错误的集合整数转换密码检查 C语言常考及易错题整理
选择题
全局、局部和静态变量
执行下面程序正确的输出是
int x5,y7;
void swap()
{int z;zx;xy;yz;
}
int main()
{ int x3,y8; swap();printf(%d,%d\nx, y);return 0;
}答案解析
正确答案3,8
swap函数调用时用的是全局变量主函数中定义的变量只在主函数中有效因为主函数也是一个函数它与其他函数是平 行关系输出语句这里考虑局部优先的原则 如下函数的f(1)的值为
int f(int n)
{static int i 1;if(n 5)return n;n n i;i;return f(n);
}答案解析
正确答案 7
此题注意静态局部变量的使用static改变了i的生命周期第一次调用函数i初值是1递归第二次调用函数时i还是第一 次那个变量值已经变成了2再一次调用函数时i就是3依次类推 以下程序的输出结果为
#include stdio.h
int i;
void prt()
{for (i 5; i 8; i)printf(%c, *);printf(\t);
}
int main()
{for (i 5; i 8; i)prt();return 0;
}答案解析
正确答案***
全局变量i在main()中修改为5第一次在prt()中执行循环输出三次*i被修改为8执行一次print(\t)回到主函数后i变为9i8为假循环结束; #define与typedef
test.c文件中包括如下语句文件中定义的四个变量中是指针类型的变量为【多选】
#define INT_PTR int*
typedef int* int_ptr;
INT_PTR a, b;
int_ptr c, d;答案解析
正确答案acd
因为#define是宏定义仅仅是直接替换,INT_PTR a, b; 进行宏替换后代码是这样的int *a, b;这里的int *是a的类型b的类型是int故此次b只是int类型
而typedef是把该类型定义一个别名别名是一个独立的类型了使用这个类型创建的变 量都是这个类型的。
所以 acd才是指针类型 以下程序结果输出是什么
#include stdio.h
#define N 2
#define M N1
#define NUM (M1)*M/2
int main()
{printf(%d\n,NUM);return 0;
}答案解析
正确答案8
宏只是替换替换后NUM的样子是(211)*21/2计算得8 转义字符
以下程序段输出结果是什么
#includestdio.h
int main()
{ char s[] \\123456\123456\t; printf(%d\n, strlen(s)); return 0;
}答案解析
正确答案12
这里考查转义字符注意\\ 表示字符\\123(ASCII码为83)表示字符S\t表示制表符这些都是一个字符 操作符
下面代码段的输出是
#include stdio.h
int main()
{int a3; printf(%d\n,(aa-a*a));return 0;
}答案解析
正确答案-12
aa-a*a等价于aa(aa-a*a)即先计算aa-a*a所以此时a的值为3-3*3-6再计算-6(-6)-12赋值给a所以a的值 为-12也就是整个表达式的值就是-12
循环
我们知道C语言的 break 语句只能跳出离它最近的一层循环可是有时候我们需要跳出多层循环下列跳出多层循环的做法正确的是【多选】 A: 将程序写成函数用return结束函数便可跳出循环
B: 修改外层循环条件例如
for( int i 0 ; i MAX1 ; i )
{for( int j 0 ; j MAX2 ; j ){if( condition ){i MAX1;break;}}
}C:在外层循环设置判断条件例如
for( ; symbol ! 1 condition2 ; )
{for( ; symbol ! 1 condition3 ; ){if( condition1 )symbol 1 ;}
}D: 在外层循环后面加入break例如
for( ; condition2 ; )
{for( ; condition3 ; ){if( condition1 )symbol 1 ;}if( symbol 1 )break ;
}答案解析
正确答案ABCD
此题旨在整理跳出多层循环的方法每个选项都是正确的代码为伪代码condition代表逻辑表达式 执行下面的程序段语句3的执行次数为
or(i 0; i n-1; i) // (1)for(j n; j i; j--) // (2)state; // (3答案解析
正确答案n(n1)/2
外循环有n次当i0,内循环为n次,当i1,内循环为n-1次,当i2时内循环为n-2次以此类推总次数为 n(n-1)(n-2)…21,就是个等差数列等于n(n1)/2 对于下面说法正确的是
t0;
while(printf(*))
{t;if (t3)break;
}
A: 其中循环控制表达式与0等价 B: 其中循环控制表达式与’0’等价 C: 其中循环控制表达式是不合法的 D: 以上说法都不对
答案解析
正确答案B
因print(“*”)函数的返回值是字符串中字符的个数即为1。所以while后面的条件恒为真所以循环控制表达式与0是等 价的字符0不是0。 设变量已正确定义以下不能统计出一行中输入字符个数不包含回车符的程序段是
A: n0;while(chgetchar()!\n) n;
B: n0;while(getchar()!\n) n;
C: for(n0;getchar()!\n;n);
D: n0;for(chgetchar();ch!\n;n);
答案解析
正确答案D
对于for循环其中第一项初始化表达式只执行一次因此ch只从输入流中取一个字符之后就再不会取字符因此会死循环 若运行以下程序时从键盘输入 ADescriptor回车 则下面程序的运行结果是
#include stdio.h
int main()
{char c;int v00,v10,v20do{switch(cgetchar()){casea:caseA:casee:caseE:casei:caseI:caseo:caseO:caseu:caseU:v1 1;defaultv0 1;v21;}}while(c!\n);printf(v0%d,v1%d,v2%d\n,v0,v1,v2);return 0;
}
答案解析
正确答案12 4 12
代码switch语句中没有break则每次找到入口进入后顺序执行到代码块结束为止。例如当c为A时从case A进入先 后执行v11;v01;v21;而当c为p时从default进入先后执行v01;v21;容易看出最终v0和v2是相等的 其他
对于下面说法正确的是
A. 对于 struct X{short s;int i;char c;}sizeof(X)等于sizeof(s) sizeof(i) sizeof(c)
B. 对于某个double变量 a可以使用 a 0.0 来判断其是否为零
C: 初始化方式 char a[14] Hello, world!; 和char a[14]; a Hello, world!;的效果相同
D: 以上说法都不对
答案解析
正确答案D
A选项没有考虑内存对齐。
B选项考察double类型的比较由于浮点数存在误差不能直接判断两个数是否相等通常采用比较两数之差的绝对值是否小于一个很小的数字具体的可自己设定这样一个数作为误差来确定是否相等。
C选项a为数组首地址是常量不能改变
所以A,B,C都是错的选择D 编程题
计算日期到天数转换 根据输入的日期计算是这一年的第几天。 保证年份为4位数且日期合法。 输入描述输入一行每行空格分割分别是年月日。 输出描述输出是这一年的第几天 这道题简单解法其实将每个月的天数枚举出来然后根据当前月份向前累加满月的天数然后再加上当前月所在的天数。最终考虑平闰年的 2 月份区别是否增加一天。 其中需要注意的是平年和闰年的判断而且是闰年的月份大于 2 的时候也就是 2 月走完总天数才能加 1 比 如 2000年2月18日 虽然是闰年但是 2月 都没走完那是不能加上闰年多出的一天的.
#include stdio.h
int is_leap_year(int year) {if (year % 4 0 year % 100 ! 0 || year % 400 0){return 1;}return 0;
}
int main()
{int month_day[] {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};int year, month, day;while (scanf(%d %d %d, year, month, day)3){int total_day day;//先把当前月份天数加上if (is_leap_year(year) month 2) { //若闰年且月份大于2月则在平年基础上1total_day 1;}for (int i month - 1; i 0; i--) {total_day month_day[i];//向前累加每月的天数即可}printf(%d\n, total_day);}return 0;
}柯尼希定理 验证尼科彻斯定理即任何一个整数m的立方都可以写成m个连续奇数之和。 例如 1^31 2^335 3^37911 4^313151719 输入一个正整数mm≤100将m的立方写成m个连续奇数之和的形式输出。 数据范围1≤m≤100 这道题的关键在于知道规律后能够找到第 n 个数据立方的起始奇数从这个起始奇数开始组成连续的n个奇数项之和的表达式即可。
等差数列和为m^3,项数为m公差d为2求首项a1
ma1 (m ( m -1 ) / 2 ) * 2 m^3
最终得到起始奇数a1 m * (m - 1) 1#include stdio.h
int main()
{int m;while(scanf(%d, m)1){int start m * (m - 1) 1;//找到对应m^3的起始奇数char buf[10240] {0};//sprintf(buf, format, ...) 与printf用法类似格式化字符串但是不用于打印而是放到一个buf中sprintf(buf, %d, start);//先将起始奇数转换成为字符串存入buf中for (int i 1; i m; i) {//然后将紧随随后的m-1个奇数数字转换为字符串按照指定格式放入buf中//%s%d, 要求先有一个字符串然后是符号然后是个数字的格式对应是buf原先的数据和奇数sprintf(buf, %s%d, buf, start2);}printf(%s\n, buf);}return 0;
}旋转数组的最小数字 描述 有一个长度为 n 的非降序数组比如[1,2,3,4,5]将它进行旋转即把一个数组最开始的若干个元素搬到数组的末尾变成一个旋转数组比如变成了[3,4,5,1,2]或者[4,5,1,2,3]这样的。请问给定这样一个旋转数组求数组中的最小值。 暴力破解遍历数组找出最小值即可
更优思想采用二分查找这个题主要分析三种旋转情况 [1, 2, 3, 4, 5]使用中间值与右端进行比较。
1. 中间大于右边 [3, 4, 5, 1, 2]这种情况下最小数一定在右边则left middle 1
2.中间等于右边 [1, 0, 1, 1, 1], 这个是[0, 1, 1, 1, 1] 旋转过来的这时候需要缩小范围 right–;注意不能是 left因为是非降序数组所以要缩小右边范围符合我们的判断规则。 3. 中间小于右边 [5, 1, 2, 3, 4], 这种情况下最小数字则在左半边则right middle
说白了最小数左右两边都非递减排列并且左排序数组大于等于右边的值
int minNumberInRotateArray(int* nums, int numsLen ) {int right numsLen - 1;int left 0;while (left right) {int mid (right - left) / 2 left;if (nums[mid] nums[right])left mid 1;else if (nums[mid] nums[right])right mid;elseright--;}return nums[left];
}错误的集合 集合 s 包含从 1 到 n 的整数。不幸的是因为数据错误导致集合里面某一个数字复制了成了集合里面的另外一个数字的值导致集合 丢失了一个数字 并且 有一个数字重复 。 给定一个数组 nums 代表了集合 S 发生错误后的结果。 请你找出重复出现的整数再找到丢失的整数将它们以数组的形式返回。 重复的数字在数组中出现 2 次丢失的数字在数组中出现 0 次其余的每个数字在数组中出现 1 次。由此可见重复的数字和丢失的数字的出现次数的奇偶性相同且和其余的每个数字的出现次数的奇偶性不同。如果在数组的 n 个数字后面再添加从 1 到 n 的每个数字得到 2n 个数字则在 2n 个数字中重复的数字出现 3 次丢失的数字出现 1 次其余的每个数字出现 2 次。根据出现次数的奇偶性可以使用异或运算求解。
用 x 和 y 分别表示重复的数字和丢失的数字。考虑上述 2n 个数字的异或运算结果 xor由于异或运算 ⊕ 满足交换律和结合律且对任何数字 a 都满足 a⊕a0 和 0⊕aa因此 xorx⊕x⊕x⊕yx⊕y即 x 和 y 的异或运算的结果。
令 lowbitxor (−xor)**则 lowbit 为 x 和 y 的二进制表示中的最低不同位**可以用 lowbit 区分 x 和 y。
得到 lowbit 之后可以将上述 2n 个数字分成两组第一组的每个数字 a 都满足 a lowbit0第二组的每个数字 b 都满足 b lowbit!0。
int* findErrorNums(int* nums, int numsSize, int* returnSize) {int* newnums (int*)malloc(2 * sizeof(int));*returnSize 2;int xor 0;for (int i 1; i numsSize; i) {xor ^ i ^ nums[i - 1];}int lowbit xor(-xor);int num1 0;int num2 0;for (int i 0; i numsSize; i) {if ((lowbit nums[i]) 0)num1 ^ nums[i];elsenum2 ^ nums[i];}for (int i 1; i numsSize; i) {if ((lowbit i) 0)num1 ^ i;elsenum2 ^ i;}// 要求第一个是重复的数,第二个是丢失的整数for (int i 0; i numsSize; i) {if (num1 nums[i]) {newnums[0] num1;newnums[1] num2;return newnums;}}newnums[0] num2;newnums[1] num1;return newnums;
}整数转换 整数转换。编写一个函数确定需要改变几个位才能将整数A转成整数B。 示例1: 输入A 29 或者0b11101, B 15或者0b01111输出2示例2: 输入A 1B 2输出2即求A与B异或的值中1的个数, 通过n(n - 1)可以去掉一个数的二进制表示的最右边的1
int convertInteger(int A, int B) {unsigned int temp A ^ B;int count 0;while (temp) {temp (temp - 1); count;}return count;
}注意这里需要用unsigned int来存储两数异或的结果因为如果用int类型当两数异或结果为
10000000000000000000000000000000即int类型能表示的负数的最小值-231
此时再实施减一操作会超出范围所以要转换为unsigned int类型 密码检查 小明同学最近开发了一个网站在用户注册账户的时候需要设置账户的密码为了加强账户的安全性小明对密码强度有一定要求 密码只能由大写字母小写字母数字构成密码不能以数字开头密码中至少出现大写字母小写字母和数字这三种字符类型中的两种密码长度至少为8 现在小明受到了n个密码他想请你写程序判断这些密码中哪些是合适的哪些是不合法的。 输入描述 输入一个数n接下来有n(n≤100)行每行一个字符串表示一个密码输入保证字符串中只出现大写字母小写字母和数字字符串长度不超过100。 输出描述 输入n行如果密码合法输出YES不合法输出NO #include stdio.h
#include string.h
int main()
{int n;while(scanf(%d, n)1) {for (int i 0; i n; i) {char password[101] {0};int upper 0, lower 0, digit 0, other 0;scanf(%s, password);//捕捉输入的密码if (strlen(password) 8) {//密码长度小于8printf(NO\n);continue;}if (password[0] 0 password[0] 9) {//密码以数字开头printf(NO\n);continue;}char *ptr password;while(*ptr ! \0) { //统计各种字符个数if (*ptr a *ptr z) lower;else if (*ptr A *ptr Z) upper;else if (*ptr 0 *ptr 9) digit;else other;ptr;}if (other 0) { // 有其他字符注意密码只能由数字和字母组成printf(NO\n);continue;}//大写小写数字必须具有两种以上而比较运算真则1假则0if ((upper0) (lower0) (digit0) 2) { // 密码只有一种字符printf(NO\n);continue;}printf(YES\n);}}return 0;
}以上就是关于C语言常考及易错题的整理啦各位大佬有什么问题欢迎在评论区指正您的支持是我创作的最大动力❤️