上一篇:从0开始学c语言-37-文件随机读写、文本文件和二进制文件、判定文件结束、文件缓冲区_阿秋的阿秋不是阿秋的博客-优快云博客
目录
题目1:多组输入打印x图形
放一下效果图,可以自己尝试写一下。
int main()
{
int i, j, n = 0;
//因为要多组输入,所以我们加了这个条件
//多组输入就是输入后还能输入
while (scanf("%d", &n) != EOF)
{
for (i = 0; i < n; i++)
{
for (j = 0; j < n; j++)
{
if ((i == j) || (i + j == n - 1))
printf("*");
else
printf(" ");
}
printf("\n");
}
}
return 0;
}
题目2:求平均分(去掉最高、最低分)
思路1:数组中排序(qsort函数),循环时候去掉最高最低分求平均分。
#include <stdlib.h>
int cmp(const void* elem1, const void* elem2)
{
return *(int*)elem1 - *(int*)elem2;
}
//求平均分
int main()
{
int arr[7] = { 0 };
int i = 0;
for (i = 0; i < 7; i++ )
{
scanf("%d", &arr[i]);
}
qsort(arr, sizeof(arr)/sizeof(arr[0]), sizeof(arr[0]), cmp);
int sum = 0;
for (i = 1; i < 6; i++)
{
sum += arr[i];
}
double output = sum / 5.0;
printf("%.2f\n", output);
return 0;
}
思路2:循环输入的同时,每次输入进行最大、最小数的判断并存储到相应的变量中,循环完后去掉最高最低分,计算平均分。
int main()
{
int num = 7;
int i = 0;
float score = 0;
float max = 0;
float min = 0;
float sum = 0;
for (i = 0; i < num; i++)
{
scanf("%d", &score);
if (score > max)
max = score;
else
min = score;
sum += score;
}
float output = sum - max - min;
printf("%.2f\n", (output/5.0));
return 0;
}
题目3:打印某年某月的天数
思路1:用结构体储存不同的天数,根据闰年和月份进行分类并打印。
enum
{
Spe_month1 = 28,
Spe_month2,
Sml_month,
Big_month
};
int main()
{
int year = 0;
int month = 0;
while (scanf("%d %d", &year, &month) != EOF)
{
//判断是不是2月
if (month == 2)
{
//是闰年,则2月29天
if ((year % 4 == 0 && year % 400 != 0) || (year % 400 == 0))
printf("day:%d\n", Spe_month2);
else
//不是,28天
printf("day:%d\n", Spe_month1);
}
//其他月份和闰年不闰年没关系
//4 6 9 11 -30
else if (month == 4 || month == 6 || month == 9 || month == 11)
printf("day:%d\n", Sml_month);
//其他情况,1 3 5 7 8 10 12 - 31天
else
printf("day:%d\n", Big_month);
}
return 0;
}
思路2:只有闰年2月的月份需要天数+1,其他天数的月份都一样,把这些天数放到数组里。
int main()
{
int y = 0;
int m = 0;
int days[] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };
while (scanf("%d %d", &y, &m) != EOF)
{
int day = days[m];
//只有闰年的2月需要天数+1
if (m == 2)
if ((y % 4 == 0 && y % 400 != 0) || (y % 400 == 0))
day += 1;
printf("%d\n", day);
}
return 0;
}
题目4:有序序列插入一个数
int main()
{
int num = 0;
//要求0<N<=50,意味着最多有51个,因为会插进来一个数字
int arr[51]; //所以数组是51
int i = 0;
scanf("%d", &num); //第一行
for (i = 0; i < num; i++)
scanf("%d", &arr[i]); //第二行
scanf("%d", &arr[i]); //第三行
int insert = arr[i];
for (i = 0; i < num + 1; i++)
{
if( (insert <= arr[i])|| (insert > arr[num]))
{
int tmp = arr[i];
arr[i] = insert;
insert = tmp;
}
printf("%d ", arr[i]);
}
return 0;
}
注意我设置的交换条件,如果小于数组中第i位的数字或者大于数组中最后一个数字,就进行交换。这是我自己假设了一个数组探索出来的条件,没啥好讲的。不懂就假设一个有序数组,慢慢推程序运行原理。
if( (insert <= arr[i])|| (insert > arr[num]))
题目5:位段判断
不会的看文章。
从0开始学c语言-32-自定义类型:结构体,枚举,联合_阿秋的阿秋不是阿秋的博客-优快云博客
int main()
{
unsigned char puc[4];
struct tagPIM
{
unsigned char ucPim1;
unsigned char ucData0 : 1;
unsigned char ucData1 : 2;
unsigned char ucData2 : 3;
}*pstPimData;
pstPimData = (struct tagPIM*)puc;
memset(puc,0,4);
pstPimData->ucPim1 = 2;
pstPimData->ucData0 = 3;
pstPimData->ucData1 = 4;
pstPimData->ucData2 = 5;
printf("%02x %02x %02x %02x\n",puc[0], puc[1], puc[2], puc[3]);
return 0;
}
结构体占用两个字节的空间,按照位段要求的bit位存放数据,结果如绿框中所示。
绿框中的数字转换为十六进制输出正好是02 29 00 00 。
顺便探索了一下十六进制%x的输出,注意10位包含0x在内的,以及不能去掉010中的第一位0,否则会是图2的效果。
题目6:模拟实现atoi函数
顺便补充:字符串转换整型 atoi、sscanf,整型转换为字符串sprintf
atoi函数是把字符串的数字转换为整型输出,我的思路是寻找数字字符,找不到数字字符的时候,就留一个指针在最后一个数字字符,然后进行整型输出(运用了指针-指针=指针之间的元素个数知识)。
int my_atoi(char* p)
{
assert(p);
//考虑什么时候读取结束
//考虑返回值是返回的谁
//考虑怎么转换为int
char* end = p;
while (*end >= '0' && *end <= '9')
{
end++;
}
--end;
int ret = 0;
int i = 1;
while (p <= end)
{
//注:直接*访问到的int值是ASCII 值,减去‘0’字符的ASCII码值正好是数字本身
ret += (*end-'0') * i;
i *= 10;
end--;
}
return ret;
}
int main()
{
char* p = "1234";
int ret = my_atoi(p);
printf("%d\n", ret);
return 0;
}
上面这个函数还是考虑不周全。
完善一下这个函数。进行空字符检查、空符号的跳过,正负号的判断。以及要知道isdigit函数和isspace函数的作用,在注释中有写。
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <ctype.h>
//isdigit函数,检查字符是否为十进制数字
//isspace函数,检查字符是否有空白
int my_atoi(const char* str)
{
//空指针检查
assert(str);
//空字符检查
if (*str == '\0')
{
return 0;
}
//跳过空白字符
while (isspace(*str))//isspace函数,检查字符是否有空白
{
//' ' '\t' '\n' '\v' '\f' '\r'
str++;
}
int flag = 1;
//跳过正负号
if (*str == '+')
{
str++;
}
else if (*str == '-')
{
flag = -1;
str++;
}
//开始转换
long long ret = 0; //因为可能超出int范围,所以进行了判断
while (isdigit(*str))
{
ret = ret * 10 + flag * (*str - '0');
//判断范围
if (ret > INT_MAX)
{
ret = INT_MAX;
return (int)ret;
}
else if (ret < INT_MIN)
{
ret = INT_MIN;
return (int)ret;
}
str++;
}
//来到这里的有两种情况
//1·遇到\0
//2·遇到数字以外的字符
return (int)ret;
}
int main(void)
{
char a[] = " -1212abcd";
int i = atoi(a);
printf(" atoi = %d\n", i);
int j = my_atoi(a);
printf("my_atoi = %d\n", j);
return 0;
}
题目7:寻找只出现一次的两个数字
在一个数组中,只有两个数字是出现了一次,其他数字都出现了两次,请找出这两个数字。
两个方法写一起了。
//方法1:两个循环遍历比对
void Find1(int* arr, int sz, int* px, int* py)
{
int tmp[2] = { 0 };
int i,j,flag,p = 0;
for (i = 0; i < sz; i++)
{
for (j = 0; j < sz; j++)
{
flag = 1;
if( (i != j) && (arr[i] == arr[j]))
{
flag = 0;
break;
}
}
//如果没有相等的数字
if (flag)
{
tmp[p++] = arr[i];
}
}
*px = tmp[0];
*py = tmp[1];
}
//根据相同数字异或为0原则思考
//把第pos位数字相同的分到一组
void Find2(int arr[], int n, int* px, int* py)
{
int i;
int sum = 0;
//先找到两个只出现一次的数,得到他们互相异或的结果
for(i = 0; i < n; i++)
{
sum ^= arr[i];
}
//再找到不一样的二进制数字位,在这一位上,两个数一定是一个1一个0
int pos;
for (i = 0; i < 32; i++)
{
//求最低位不同还有两种:ret=ret&(-ret)或ret=ret&(~ret-1)
//这两种我没有验证,只是有人说而已
if (sum & 1 << i)
{
pos = i;
break;
}
}
//假设倒数第5位的二进制数字不一样
//那就是根据这个倒数第五位进行分组
//把能够异或为0的放在一起
//把两个不同数字分在两个组
*px = *py = 0;
for (i = 0; i < n; i++)
{
if (arr[i] & 1 << pos)
{
*px ^= arr[i]; //这一位是1的,放在数1里
}
else
{
*py ^= arr[i]; //这一位是0的,放在数2里
}
}
}
int main()
{
int arr[] = { 1,1,2,2,3,3,4,4,5,6 };
int sz = sizeof(arr) / sizeof(arr[0]);
int x, y;
/*Find1(arr, sz, &x, &y);*/
Find2(arr, sz, &x, &y);
printf("%d %d", x, y);
return 0;
}
题目8:模拟实现strncpy函数
当字符串复制的时候,判断 需要赋值字符串 是否到了\0的位置,以及 是否到达了复制字符串的制定个数,如果指定复制的字符个数还未到就到了\0的位置,那么需要给字符串中加上\0字符。
char * mystrncpy(char * dst, const char * src, size_t n)
{
int i;
for (i = 0; src[i] && i < n; i++)
{
dst[i] = src[i];
}
if (i < n)
{
dst[i] = 0;
}
return dst;
}
题目9:模拟实现strncat函数
进行字符串追加的时候,先要找到第一个字符串中最后一个字符的位置,也就是\0的位置,然后进行字符串的追加,当第二个字符串未到达\0位置以及追加字符个数未达到时候,便继续追加,最后需要我们手动加一个\0结束字符。
char * mystrncat(char * dst, const char * src, size_t n)
{
char * tmp = dst;
while (*dst)
{
dst++;
}
int i;
for (i = 0; src[i] && i < n; i++)
{
dst[i] = src[i];
}
dst[i] = 0;
return tmp;
}