C语言进阶习题练习6

Posted Huang_ZhenSheng

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C语言进阶习题练习6相关的知识,希望对你有一定的参考价值。

目录

1.公务员面试现场打分。有7位考官,从键盘输入若干组成绩,每组7个分数(百分制),去掉一个最高分和一个最低分,输出每组的平均成绩。

2.描述有一个有序数字序列,从小到大排序,将一个新输入的数插入到序列中,保证插入新数后,序列仍然是升序。

3.下面代码的输出结果为

4.模拟实现atoi《剑指OFFER》

5.找单身狗:一个数组中只有两个数字是出现一次,其他所有数字都出现了两次。

6.交换奇偶位

写一个宏,可以将一个整数的二进制位的奇数位和偶数位交换。

7.offsetof宏

写一个宏计算结构体中某变量相对于首地址的偏移,并给出说明


1.公务员面试现场打分。有7位考官,从键盘输入若干组成绩,每组7个分数(百分制),去掉一个最高分和一个最低分,输出每组的平均成绩。

输入描述:一行,输入7个整数(0~100),代表7个成绩,用空格分隔。

输出描述:一行,输出去掉最高分和最低分的平均成绩,小数点后保留2位,每行输出后换行。

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int main()
{
    int i = 0;
    int sum = 0;
    int min = 100;//假设最小值是100
    int max = 0;//假设最大值是0
    int score = 0;
    for(i=0; i<7; i++)
    {
        scanf("%d ", &score);
        sum += score;
        if(score > max)
            max = score;
        if(score < min)
            min = score;
    }
    printf("%.2f\\n", (sum-min-max)/5.0);
    return 0;
}

2.描述有一个有序数字序列,从小到大排序,将一个新输入的数插入到序列中,保证插入新数后,序列仍然是升序。

输入描述:

第一行输入一个整数(0≤N≤50)。

第二行输入N个升序排列的整数,输入用空格分隔的N个整数。

第三行输入想要进行插入的一个整数。

输出描述:

输出为一行,N+1个有序排列的整数。

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int main()
{
	int n = 0;
	scanf("%d",&n);
	int i = 0;
	int arr[51] = { 0 };
	for (i = 0; i < n; i++)
	{
		scanf("%d",&arr[i]);
	}
	int m = 0;
	scanf("%d",&m);
	for (i = n - 1; i >= 0; i--)
	{
		if (arr[i] > m)
			arr[i + 1] = arr[i];
		else
		{
			break;
		}
	}
	arr[i + 1] = m;
	for (int i = 0; i <= n; i++)
	{
		printf("  %d",arr[i]);
	}
	return 0;
}

3.下面代码的输出结果为

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;
}

4.模拟实现atoi《剑指OFFER》

//<剑指offer>
#include <assert.h>
#include <ctype.h>
#include <limits.h>
enum State
{
	INVALID,//0
	VALID   //1
};
state 记录的是my_atoi 返回的值是合法转化的值,还是非法的状态
//
enum State state = INVALID;


int my_atoi(const char* s)
{
	int flag = 1;
	//assert(NULL != s);
	// 
	//空指针
	if (NULL == s)
	{
		return 0;
	}
	//空字符
	if (*s == '\\0')
	{
		return 0;
	}
	//跳过空白字符
	while (isspace(*s))
	{
		s++;
	}
	//+/-
	if (*s == '+')
	{
		flag = 1;
		s++;
	}
	else if (*s == '-')
	{
		flag = -1;
		s++;
	}
	//处理数字字符的转换
	long long n = 0;
	while (isdigit(*s))
	{
		n = n * 10 + flag*(*s - '0');
		if (n > INT_MAX || n < INT_MIN)
		{
			return 0;
		}
		s++;
	}
	if (*s == '\\0')
	{
		state = VALID;
		return (int)n;
	}
	else
	{
		//state = VALID;
		//非数字字符的情况
		return (int)n;
	}
}
int main()
{
	//1. 空指针
	//2. 空字符串
	//3. 遇到了非数字字符
	//4. 超出范围
	
	//const char* p = "-123111111111111111111111111111111111111";
	//"0"
	//int ret = my_atoi(p);
	const char* p = "     -123a";
	int ret = my_atoi(p);


	if (state == VALID)
		printf("正常的转换:%d\\n", ret);
	else
		printf("非法的转换:%d\\n", ret);


	return 0;
}

5.找单身狗:一个数组中只有两个数字是出现一次,其他所有数字都出现了两次。

编写一个函数找出这两个只出现一次的数字。

思路:

//1^2^3^4^5^6^1^2^3^4^5 = 5^6 = 3!=0
//1 3 1 3 5
//2 4 2 4 6
//1.分组
//2.分组的要点:5和6必须在不同的组
//找出这两个只出现一次的数字 

void Find(int arr[], int sz,int*x,int*y)
{
	int ret = 0;
	int i = 0;
	for (i = 0; i < sz; i++)
	{
		ret = arr[i]^ret;
	}
	//2.计算ret哪一位为1
	int pos = 0;
	for (i = 0; i < 32; i++)
	{
		if (((ret >> i) & 1) == 1)
		{
			pos = i;
			break;
		}
	}
	//把从低位向高的第pos位为1,为0的放在另一个组
	int num1 = 0;
	int num2 = 0;
	for (i = 0; i < sz; i++)
	{
		if (((arr[i] >> pos) & 1) == 1)
		{
			num1 = num1^arr[i];
		}
		else
		{
			num2 = num2^arr[i];
		}
	}
	*x = num1;
	*y = num2;
}
int main()
{
	int arr[] = { 1, 2, 3, 4, 5, 7, 4, 3, 2, 1 };
	int sz = sizeof(arr) / sizeof(arr[0]);
	int x = 0;
	int y = 0;
	//1.要把所有数字异或
	Find(arr, sz,&x,&y);
	printf("%d %d", x, y);
	return 0;
}

6.交换奇偶位

写一个宏,可以将一个整数的二进制位的奇数位和偶数位交换。

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#define SWAP(N)((N & 0xaaaaaaaa) >> 1)+((N & 0x55555555)<< 1)
int main()
{
	//10
	//00000000 00000000 00000000 00001010
	int num = 10;
	int ret = SWAP(num);
	//int ret = ((num & 0xaaaaaaaa) >> 1)+((num & 0x55555555)<<1);
	printf("%d",ret);
	return 0;
}

7.offsetof宏

写一个宏计算结构体中某变量相对于首地址的偏移,并给出说明

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stddef.h>
struct A
{
	int a;
	short b;
	int c;
	char d;
};
#define OFFSETOF(struct_name,mem_name) (int)&(((struct_name*)0)->mem_name)
int main()
{
	printf("%d\\n", OFFSETOF(struct A, a));
	printf("%d\\n", OFFSETOF(struct A, b));
	printf("%d\\n", OFFSETOF(struct A, c));
	printf("%d\\n", OFFSETOF(struct A, d));
}

以上是关于C语言进阶习题练习6的主要内容,如果未能解决你的问题,请参考以下文章

C语言进阶学习笔记二指针的进阶(重点必看+代码演示+练习)

C语言指针进阶第五站,函数指针

C语言指针练习题

C语言指针练习题

mysql练习题进阶版

明解c语言第三版 入门篇 练习题答案 第六章 第6-11题解法。函数相关的问题。