2022-05-09_算术转换
1. 自动类型转换(整型提升)
下面代码的结果是:
#include <stdio.h>
int i;
int main()
{
i--;
if (i > sizeof(i))
{
printf(">\n");
}
else
{
printf("<\n");
}
return 0;
}
A.>
B.<
C.不输出
D.程序有问题
【答案解析】
i的初始值为0,i–结果-1,i为整形,sizeof(i)求i类型大小是4,按照此分析来看,结果应该选择B,
故实际应该选择A,这道题其实很隐蔽,真是虾仁猪心!!!
2. 找规律:X型图案
找到规律,左斜线就是i = j,右斜线就是i+j = n-1
#include <stdio.h>
int main()
{
int n = 0;
while(scanf("%d", &n) != EOF)
{
int i = 0;
int j = 0;
for(i=0; i<n; i++)
{
for(j=0; j<n; j++)
{
if(i == j)//左斜线
printf("*");
else if(i+j == n-1)//右斜线
printf("*");
else
printf(" ");
}
printf("\n");
}
}
return 0;
}
3. 数组存储月份天数
闰年的判断,通过数组存储对应的天数
#include <stdio.h>
int is_leap_year(int y)
{
return (((y % 4 == 0) && (y % 100 != 0)) || (y % 400 == 0));
}
int main()
{
int y = 0;
int m = 0;
int d = 0;
int days[13] = { 0, 31,28,31,30,31,30,31,31,30,31,30,31 };
// 1 2 3 ....
//0表示假
//非0表示真
//逻辑操作符 && || ! 的结果如果是真就是1,如果是假就是0
while (scanf("%d %d", &y, &m) == 2)
{
int d = days[m];
if ((is_leap_year(y) == 1) && (m == 2))
{
d++;
}
printf("%d\n", d);
}
return 0;
}
scanf函数的返回值 如果读取到了1个就返回1 未读取到就返回EOF
4. 三角形判断
#include <stdio.h>
int main()
{
int a = 0;
int b = 0;
int c = 0;
while(~scanf("%d %d %d", &a, &b, &c))
{
if((a+b>c) && (a+c>b) && (b+c>a))
{
//三角形
if(a==b && b==c)//等边三角形
{
printf("Equilateral triangle!\n");
}
else if(((a==b)&&(b!=c)) || ((a==c)&&(c!=b)) || ((b==c)&&(c!=a)))//等腰
{
printf("Isosceles triangle!\n");
}
else
{
printf("Ordinary triangle!\n");
}
}
else
{
//不是三角形
printf("Not a triangle!\n");
}
}
return 0;
}
思路:先判断是不是三角形,再判断是不是等边三角形,然后是等腰条件
2022-05-11-指针概念
5. 地址+定值
下列程序段的输出结果为( )
unsigned long pulArray[] = {6,7,8,9,10};
unsigned long *pulPtr;
pulPtr = pulArray;
*(pulPtr + 3) += 3;
printf("%d,%d\n",*pulPtr, *(pulPtr + 3));
A.9,12
B.6,9
C.6,12
D.6,10
【答案解析】
地址+定值并不会引起地址的改变 pulPtr 还是指向首元素
6. 指针偏移
下面关于指针运算说法正确的是:( )
A.整形指针+1,向后偏移一个字节
B.指针-指针得到是指针和指针之间的字节个数
C.整形指针解引用操作访问4个字节
D.指针不能比较大小
【答案解析】
注意:此题是有问题的,说法不严谨,如果将整形指针理解成int*类型的指针,那么一下说法解析如下:
A:错误,整形指针+1,向后便移一个整形类型的大小,即4个字节
B:错误,两个指针相减,指针必须指向一段连续空间,减完之后的结构代表两个指针之间相差元素的个数
C:正确,整形指向的是一个整形的空间,解引用操作访问4个字节
D:指针中存储的是地址,地址可以看成一个数据,因此是可以比较大小的
7. 大小端问题
在小端机器中,下面代码输出的结果是:( )
#include <stdio.h>
int main()
{
int a = 0x11223344;
char *pc = (char*)&a;
*pc = 0;
printf("%x\n", a);
return 0;
}
作业内容
A.00223344
B.0
C.11223300
D.112233
答案解析:
假设,a变量的地址为0x64,则a变量在内存中的模型为:
0x64| 44 |
0x65| 33 |
0x66| 22 |
0x67| 11 |
char*
类型的指针变量pc指向只能指向字符类型的空间,如果是非char类型的空间,必须要将该空间的地址强转为char*
类型。
char *pc = (char*)&a;
pc实际指向的是整形变量a的空间,即pc的内容为0x64,即44,
*pc=0
,即将44位置中内容改为0,修改完成之后,a中内容为:0x11223300
8. gets 和 scanf 区别
【答案解析】
void reverse(char* arr)
{
// 就是正常交换left、right下标对应的元素即可
int left = 0;
int right = strlen(arr)- 1;
while (left <= right)
{
char tmp = arr[left];
arr[left] = arr[right];
arr[right] = tmp;
left++;
right--;
}
}
int main()
{
char arr[10001] = { 0 };
gets(arr);
reverse(arr);
printf("%s", arr);
return 0;
}
注意:如果是在线OJ时,必须要考虑循环输入,因为每个算法可能有多组测试用例进行验证,在获取字符串的过程中,采用gets方法(头文件stdio.h),scanf读取到空格就会停止
9. “水仙花数”
打印水仙花数
求出0~100000之间的所有“水仙花数”并输出。
“水仙花数”是指一个n位数,其各位数字的n次方之和确好等于该数本身,如:153=13+53+3^3,则153是一个“水仙花数”。
/*
思路:
此题的关键在于只要知道判断一个数据是否为水仙花数的方式,问题就迎刃而解。假定给定一个数据data,具体检测方式如下:
1. 求取data是几位数
2. 获取data中每个位置上的数据,并对其进行立方求和
3. 对data中每个位上的数据立方求和完成后,在检测其结果是否与data相等即可,
相等:则为水仙花数
否则:不是
具体实现参考以下代码。
*/
int main()
{
int i = 0;
for(i=0; i<=999999; i++)
{
int count = 1;
int tmp = i;
int sum = 0;
//判断i是否为水仙花数
//1. 求判断数字的位数
while(tmp/10)
{
count++;
tmp = tmp/10;
}
//2. 计算每一位的次方和
tmp = i;
while(tmp)
{
sum += pow(tmp%10, count);
tmp = tmp/10;
}
//3. 判断
if(sum == i)
printf("%d ", i);
}
return 0;
}
2022-05-13-指针(初阶)
10. 结构体访问成员变量
结构体访问成员的操作符不包含:( )
A. . 操作符
B. -> 操作符
C. * 解引用操作符
D. sizeof
【答案解析】
A:正确,结构体类型变量访问结构体中成员时,使用.操作符
B:正确,指向结构体类型变量的指针访问结构体中成员时,使用->操作符
C:正确,指向结构体类型变量的指针也可以通过.方式访问成员,只不过要先通过*对该指针解引用
D:错误,sizeof是求结构体类型大小的
11. 运算符优先级
下面程序要求输出结构体中成员a的数据,以下不能填入横线处的内容是( )
#include < stdio.h >
struct S
{
int a;
int b;
};
int main( )
{
struct S a, *p=&a;
a.a = 99;
printf( "%d\n", __________);
return 0;
}
A.a.a
B.*p.a
C.p->a
D.(*p).a
【答案解析】B
结构体类型变量需要访问其成员时,用.运算符,如果是指向结构体变量的指针访问时,需要用->,或者先对指针解引用,取到指向的结构体类型的变量,再通过.访问,但是要注意优先级
2022-05-16-使用调试技巧
12. const 修饰变量
语言中哪一种形式声明了一个指向char类型变量的指针p,p的值不可修改,但p指向的变量值可修改?( )
A.const char *p
B.char const *p
C.char* const p
D.const char *const p
【答案解析】C
A:错误,const修饰*p,表示p指向的内容不能修改
B:错误,同上
C:正确,const修饰p本身,表示p的指向不能修改,p指向的空间中内容可以修改
D:错误,第一个const表示p指向的内容不能修改,第二个const表示p不能指向其他变量
13. Debug 和Release 版本的区别
关于Debug和Release的区别说法错误的是:( )
A.Debug被称为调试版本,程序调试找bug的版本
B.Release被称为发布版本,测试人员测试的就是Release版本
C.Debug版本包含调试信息,不做优化。
D.Release版本也可以调试,只是往往会优化,程序大小和运行速度上效果最优
【答案解析】D
A:正确,Debug为调试版本,一般在开发完成后发布工程前,调试代码都是在Debug模式下进行的
B:正确,Release版本最终是要发送给用户的,发给用户的版本必须要没有问题,测试人员就是最后一个把关的
C:正确,Debug版本是调试版本,编译器编译时会增加一些调试信息,编译器基本不会对其进行优化
D:错误,Release版本是不能调试的,一般都是在Debug版本下调试的, Release版本一般编译器会进行大量的优化,删除无用的代码,指令的次序调整等,让其速度更快
14. 奇在前,偶在后
调整奇数偶数顺序
调整数组使奇数全部都位于偶数前面。
输入一个整数数组,实现一个函数,来调整该数组中数字的顺序使得数组中所有的奇数位于数组的前半部分,所有偶数位于数组的后半部分。
思路:从前向后找偶数,从后往前找奇数,找到后两两进行交换
【答案解析】
//输入一个整数数组,实现一个函数,
//来调整该数组中数字的顺序使得数组中所有的奇数位于数组的前半部分,
//所有偶数位于数组的后半部分。
//
void move_odd_even(int arr[], int sz)
{
int left = 0;
int right = sz - 1;
while (left<right)
{
//从左向右找一个偶数,停下来
while ((left<right) && (arr[left] % 2 == 1))
{
left++;
}
//从右向左找一个奇数,停下来
while (((left < right)) && (arr[right] % 2 == 0))
{
right--;
}
//交换奇数和偶数
if (left < right)
{
int tmp = arr[left];
arr[left] = arr[right];
arr[right] = tmp;
left++;
right--;
}
}
}
int main()
{
int arr[10] = { 0 };
//输入
int i = 0;
int sz = sizeof(arr) / sizeof(arr[0]);
for (i = 0; i < sz; i++)
{
//scanf("%d", &arr[i]);
scanf("%d", arr+i);
}
//1 2 3 4 5 6 7 8 9 10
//调整
move_odd_even(arr, sz);
//输出
for (i = 0; i < sz; i++)
{
printf("%d ", arr[i]);
}
return 0;
}
2022-05-21-简单
15. 取出每个位 %10/10
16. 找规律:打印直角三角形空格
2022-05-21-测评
17. 曲解题意
【2分】假定×和y为double型,则执行
x=2 ; y=x+3/2;
后y的值为()
A 3.500000
B 3
C 2.000000
D 3.000000
【答案解析】D
题目中说x,y是double类型x=2 并不是说将int类型的2,赋值给了x x,y是double类型是大条件
即使是将整型的2赋值给double类型也会发生整型提升,所以x=2.00000000
18. 指针的移动
【2分】若有定义语句:
int year=1009,*p=&year;
以下不能使变量year中的值增至1010的语句是
A. *p+=1;
B. (*p)++;
C. ++(*p);
D. *p++;
【答案解析】D
其他选项都是解引用后赋值
这里的D选项:++是后置的,所以表达式的值先返回(*p) 再让p++;
而p是指针,p++是往后移动4个字节(因为是int类型) ,就导致指针p指向其他位置
如图所示:
19. 倒置字符串
#include <stdio.h>
#include <assert.h>
void reverse(char* left, char* right)
{
assert(left);
assert(right);
while (left < right)
{
char tmp = *left;
*left = *right;
*right = tmp;
left++;
right--;
}
}
int main()
{
char arr[101] = { 0 };
//输入
gets(arr);//I like beijing.
//逆置
int len = strlen(arr);
//1. 逆序整个字符串
reverse(arr, arr + len - 1);
//2. 逆序每个单词
char* start = arr;
while (*start)
{
char* end = start;
while (*end != ' ' && *end != '\0')
{
end++;
}
reverse(start, end - 1);
if (*end != '\0')
end++;
start = end;
}
//输出
printf("%s\n", arr);
return 0;
}
将要逆置的left指针与right指针传参,分别针对整个字符串和单词逆置,单词范围的锁定
end指针和start指针不能越界访问,要加
if (*end != '\0')
end++;
20. Fib计算次数
总共调用67次(红色相加)