c语言---刷题01

目录

1.static

2.根据公式计算m的值

3. 输入5个学生各5科成绩,输出5个学生各5科成绩及总分。

4.最大公约数

5.闰年

6.素数

7.计算1/1-1/2+1/3-1/4+1/5 …… + 1/99 - 1/100 的值

8.求10个整数中最大值

9.输出9*9乘法口诀表

10.能把arr1中的abcdef拷贝到arr2中

11.调用memset()函数

12.写一个函数可以找出两个整数中的最大值

13.写一个函数可以交换两个整形变量的内容

14.通过指针位置来修改数据

15.写一个函数可以判断一个数是不是素数

16.写一个函数判断一年是不是闰年

17.写一个函数,实现一个整形有序数组的二分查找

18.写一个函数,每调用一次这个函数,就会将 num 的值增加1

19.strlen()和printf()函数演示

20.编写一个print函数把num的每一位按照顺序打印出来

21.编写函数不允许创建临时变量,求字符串的长度

22.求阶乘

23.斐波那契数列

24.字符串逆序输出

25.写一个递归函数DigitSum(n),输入一个非负整数,返回组成它的数字之和

26.编写一个函数实现n的k次方,使用递归实现

27.逗号表达式的数组大小

28.区分sizeof( )和 strlen( )

29.创建一个整形数组,实现以下功能

30.将数组A中的内容和数组B中的内容进行交换(数组一样大)

31.左移、右移操作符

32.按位与、按位或、按位异或

33.不创建临时变量(第三个变量),实现两个数的交换

34.编写代码实现:求一个整数存储在内存中的二进制中1的个数

35.C语言中C99之前没有表示真假的类型  C99中引用了布尔类型

36.sizeof()

37.按位取反~ 

38.把二进制里面的倒数的第三个数字0换做1 

39.++和--

40.&&和| |

41.逗号表达式

42.输出数组指定元素

43.修改结构体内数据及调用输出

44.整体提升

45.求两个数二进制中不同位的个数

46.打印整数二进制的奇数位和偶数位

47.统计二进制中1的个数

48.求代码输出结果

49.写一个函数打印arr数组的内容,不使用数组下标,使用指针

50.求出0~100000之间“水仙花数”,打印菱形


1.static

#include <stdio.h>
int sum(int a)    //8, 10, 12, 14, 16,
{
    int c = 0;
    static int b = 3;
    c += 1;
    b += 2;
    return (a + b + c);
}
int main()
{
    int i;
    int a = 2;
    for (i = 0; i < 5; i++)
    {
        printf("%d", sum(a));
    }
}

结果:8, 10, 12, 14, 16

2.根据公式计算m的值

其中 max3函数为计算三个数的最大值,如: max3(1, 2, 3) 返回结果为3。

#include<stdio.h>
int max3(int a, int b, int c) 
{
	int max = a;
	if (max < b)
		max = b;
	if (max < c)
		max = c;
	return max;
}

int main() {
	int a=0, b=0, c=0;
	double m=0.0;
	scanf("%d %d %d", &a, &b, &c);
	m = max3(a + b, b, c) * 1.0 / (max3(a, b + c, c) + max3(a, b, b + c));
	printf("%.2lf", m);
	return 0;
}

3. 输入5个学生各5科成绩,输出5个学生各5科成绩及总分。

循环


int main()
{
    int i, j;
    double a;
    double sum;
    for (i = 0; i < 5; i++)
    {
        sum = 0.0;
        for (j = 0; j < 5; j++)
        {
            scanf("%lf", &a);
            sum += a;
            printf("%.1f ", a);
        }
        printf("%.1f\n", sum);
    }
}

数组

int main() 
{
    float arr[5][6];
    int i, j;
    for (i = 0; i < 5; i++) 
    {
        float sum = 0;
        for (j = 0; j < 5; j++) 
        {
            scanf("%f", &arr[i][j]);
            sum += arr[i][j];
        }
        arr[i][5] = sum;
    }
    for (i = 0; i < 5; i++) 
    {
        for (j = 0; j < 6; j++) 
        {
            printf("%.1f ", arr[i][j]);
        }
        printf("\n");
    }
    return 0;
}

 4.最大公约数

辗转相除法

#include<stdio.h>
int main()
{
    int a, b, i, gcd;
    scanf("%d %d", &a, &b);
    for (i = 1; i < a && i < b; i++)   
    {
        if (a % i == 0 && b % i == 0) 
            gcd = i;
    }
    printf("%d和%d的最大公约数为%d\n", a, b, gcd);
    return 0;
}

逐一试

int main()
{
	int a = 0;
	int b = 0;
	scanf("%d %d", &a, &b);
	int m = (a > b ? b : a);
	//假设m就是最大公约数
	while (1)
	{
		if (a % m == 0 && b % m == 0)
		{
			break;
		}
		m--;
	}
	printf("%d\n", m);
	return 0;
}

5.闰年

#include <stdio.h>
int main()
{
    int year = 0;
    for (year = 1000; year <= 2000; year++)
    {
        if ((year % 4 == 0 && year % 100 != 0)||( year % 400 == 0))
            printf("%d\n", year);
    }
    return 0;
}

6.素数

#include <stdio.h>
int main()
{
	int i = 100;
	int j = 200;
	int m = 2;
	for (i = 101; i <= j; i += 2)
	{
		for (m = 3; m < i; m++)
		{
			if (i % m == 0)
			{
				break;
			}
			if ((i % m != 0) && (m >= i / 2))
			{
				printf("%d  ", i);
				break;
			}
		}
	}
	return 0;
}

int main()
{
	int i = 0;
	int count = 0;
	for (i = 101; i <= 200; i+=2)
	{
		int flag = 1;//假设i是素数
		//判断i是否为素数
		int j = 0;
		for (j = 2; j<=sqrt(i); j++)
		{
			if (i % j == 0)
			{
				flag = 0;//i不是素数
				break;
			}
		}
		if (flag == 1)//说明i是素数
		{
			printf("%d ", i);
			count++;
		}
	}
	printf("\ncount = %d\n", count);
	return 0;
}

 7.计算1/1-1/2+1/3-1/4+1/5 …… + 1/99 - 1/100 的值

#include<stdio.h>
int main()
{
	int n;
	float i = 1.0;
	float sum = 0;
	for (n = 1; n <= 100; n++)
	{
		sum = sum + (i / n) * j;
		j = -j;//用于正负号转换
	}
	printf("%f\n", sum);
	return 0;
}

8.求10个整数中最大值

#include <stdio.h>
int main() {
	int i = 0;
	int Max = 0;
	int arr[10] = { 0 };
	for (i = 0; i < 10; i++) 
	{
		scanf("%d", &arr[i]);
	}
	Max = arr[0];
	for (i = 0; i < 10; i++) 
	{
		if (arr[i] > Max) 
		{
			Max = arr[i];
		}
	}
	printf("最大的数为%d ", Max);
	return 0;
}

9.输出9*9乘法口诀表

int main()
{
	int i = 0, j = 0;
	for (i = 1; i <= 9; i++)
	{
		for (j = 1; j <= i; j++)
		{
			printf("%d*%d=%d ", i, j, i * j);
		}
		printf("\n");
	}
	return 0;
}

10.能把arr1中的abcdef拷贝到arr2中


int main()
{
	char arr1[] = "abcdef";       
	char arr2[20] = "XXXXXXXXXXX";
	strcpy(arr2, arr1);
	printf("%s\n", arr2);
	return 0;
}

11.调用memset()函数

int main()
{
	char arr[] = "hello bit";
	memset(arr + 6, 'X', 3);
	//1. 设置内存的时候是以字节为单位的
	//2. 每个字节的内容都是一样value
	printf("%s\n", arr);//XXXXX bit   输出hello XXX
	return 0;
}

12.写一个函数可以找出两个整数中的最大值

int get_max(int x, int y)
{
	return (x > y ? x : y);
}
int main()
{
	int a = 0;
	int b = 0;
	scanf("%d %d", &a, &b);
	int m = get_max(a, b);
	printf("%d\n", m);
	return 0;
}

13.写一个函数可以交换两个整形变量的内容

//当实参传给形参的时候,形参是实参的一份临时拷贝,对形参的修改不会影响实参

//实现成函数,但是不能完成任务  形参  传值
void Swap1(int x, int y)
{
	int tmp = 0;
	tmp = x;
	x = y;
	y = tmp;
}

正确的版本  实参  传址
void Swap2(int* px, int* py)
{
	int tmp = 0;
	tmp = *px;
	*px = *py;
	*py = tmp;
}

int main()		//Swap1::num1 = 1 num2 = 2	输出结果
                  //Swap2::num1 = 2 num2 = 1
{
	int num1 = 1;
	int num2 = 2;
	Swap1(num1, num2);
	printf("Swap1::num1 = %d num2 = %d\n", num1, num2);
	Swap2(&num1, &num2);
	printf("Swap2::num1 = %d num2 = %d\n", num1, num2);
	return 0;
}

14.通过指针位置来修改数据

int main()
{
	int a = 10;
	int* pa = &a;
	*pa = 20;
	printf("%d\n", a);
	return 0;
}

15.写一个函数可以判断一个数是不是素数

#include <math.h>
int is_prime(int n)
{
	int j = 0;
	for (j = 2; j <= sqrt(n); j++)
	{
		if (n % j == 0)
		{
			return 0;    //返回0 表示不是素数
		}
	}
	return 1;            //返回1 表示是素数
}
int main()
{
	int i = 0;
	for (i = 100; i <= 200; i++)
	{
		if (is_prime(i) == 1)
		{
			printf("%d ", i);
		}
	}
	return 0;
}

16.写一个函数判断一年是不是闰年

int is_leap_year(int y)
{
	if (((y % 4 == 0) && (y % 100 != 0)) || (y % 400 == 0))
		return 1;
	else
		return 0;
}
int is_leap_year(int y)
{
	return ((y % 4 == 0) && (y % 100 != 0)) || (y % 400 == 0);
}
int main()
{
	int y = 0;
	for (y = 1000; y <= 2000; y++)
	{
		if (is_leap_year(y) == 1)
		{
			printf("%d ", y);
		}
	}
	return 0;
}

17.写一个函数,实现一个整形有序数组的二分查找

        正确代码

int binary_search(int arr[], int k, int sz)
{
	int left = 0;
	int right = sz - 1;
	while (left<=right)
	{
		int mid = left + (right - left) / 2;
		if (arr[mid] < k)
		{
			left = mid + 1;
		}
		else if (arr[mid] > k)
		{
			right = mid - 1;
		}
		else
		{
			return mid;
		}
	}
	return -1;//找不到
}
int main()
{
	//数组在传参的时候,传递不是整个数组
	//传递是数组首元素的地址
	int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
	int k = 0;
	scanf("%d", &k);
	int sz = sizeof(arr) / sizeof(arr[0]);
	int ret = binary_search(arr, k, sz);
	if (-1 == ret)
		printf("找不到\n");
	else
		printf("找到了,下标是:%d\n", ret);
	return 0;
}

        错误代码

int binary_search(int arr[], int k)
{
	int sz = sizeof(arr) / sizeof(arr[0]);  //error
	int left = 0;
	int right = sz - 1;
	while (left <= right)
	{
		int mid = left + (right - left) / 2;
		if (arr[mid] < k)
		{
			left = mid + 1;
		}
		else if (arr[mid] > k)
		{
			right = mid - 1;
		}
		else
		{
			return mid;
		}
	}
	return -1;//找不到
}
int main()
{
	int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
	int k = 0;
	scanf("%d", &k);
	int ret = binary_search(arr, k);  //错误的示范
	if (-1 == ret)
		printf("找不到\n");
	else
		printf("找到了,下标是:%d\n", ret);
	return 0;
}

18.写一个函数,每调用一次这个函数,就会将 num 的值增加1

void test(int *p)
{
	*p = *p + 1;    //(*p)++  等价
}
int main()
{
	int num = 0;
	test(&num);
	printf("%d\n", num);   //1
	test(&num);
	printf("%d\n", num);   //2
	test(&num);
	printf("%d\n", num);   //3
	test(&num);
	printf("%d\n", num);   //4
	return 0;
}

19.strlen()和printf()函数演示

int main()
{
	int len = strlen("abcdef");
	printf("len1 = %d\n", len);
	printf("len2 = %d\n", strlen("abcdef"));
	printf("%d", printf("%d", printf("%d", 43)));  
    //4321   printf的返回值是字符的个数
  return 0;
}

20.编写一个print函数把num的每一位按照顺序打印出来

void print(int n)
{
	if (n > 9)
	{
		print(n/10);
	}
	printf("%d ", n % 10);
}
int main()
{
	unsigned int num = 0;
	scanf("%d", &num);
	print(num);
	return 0;
}

21.编写函数不允许创建临时变量,求字符串的长度

#include <string.h>
int my_strlen(char* str)   //这是创建临时变量count的写法
{
	int count = 0;           //统计字符的个数
	while (*str != '\0')
	{
		count++;
		str++;
	}
	return count;
}

//my_strlen("abcdef")
//1+my_strlen("bcdef")
//1+1+my_strlen("cdef")
//1+1+1+ my_strlen("def")
//1+1+1+1+ my_strlen("ef")
//1 + 1 + 1 + 1 +1+my_strlen("f")
//1 + 1 + 1 + 1 + 1 + 1+ my_strlen("")
//1 + 1 + 1 + 1 + 1 + 1 + 0 = 6

int my_strlen(char* str)
{
	if (*str != '\0')
		return 1 + my_strlen(str+1);
	else
		return 0;
}
int main()
{
	char arr[] = "abcdef";
	int len = my_strlen(arr);
	printf("%d\n", len);
	return 0;
}

22.求阶乘

int fac1(int n)   //递归法
{
	if (n <= 1)
		return 1;
	else
		return n * fac(n - 1);
}
int fac(int n)
{
	int i = 0;
	int ret = 1;
	for (i = 1; i <= n; i++)
	{
		ret = ret * i;
	}
	return ret;
}
int main()
{
	int n = 0;
	scanf("%d", &n);
	int ret = fac(n);
	printf("%d\n", ret);
	return 0;
}

 23.斐波那契数列

int count = 0;
int fib(int n)   //递归法  占用内存过大  计算较慢
{
	if (n == 3)
		count++;   //count用来计算求这个斐波那契数列的次数
	if (n <= 2)
		return 1;
	else
		return fib(n - 1) + fib(n - 2);
}
int fib(int n)   //循环法   优先选择
{
	int a = 1;
	int b = 1;
	int c = 1;
	while (n>2)
	{
		c = a + b;
		a = b;
		b = c;
		n--;
	}
	return c;
}
int main()
{
	int n = 0;
	scanf("%d", &n);
	int ret = fib(n);
	printf("%d\n", ret);
	printf("count = %d\n", count);
	return 0;
}

24.字符串逆序输出

方法一:指针


void reverse_string(char* str)
{
	int len = strlen(str);
	char* left = str;
	char* right = str+len-1;
	while (left<right)
	{
		char tmp = *left;
		*left = *right;
		*right = tmp;
		left++;
		right--;
	}
}

 方法二:数组


void reverse_string(char arr[])
{
	int len = strlen(arr);
	int left = 0;
	int right = len - 1;

	while (left<right)
	{
		char tmp = arr[left];
		arr[left] = arr[right];
		arr[right] = tmp;
		left++;
		right--;
	}
}

 方法三:递归


void reverse_string(char* str)
{
	int len = strlen(str);
	char tmp = *str;
	*str = *(str + len - 1);
	*(str + len - 1) = '\0';
	if(strlen(str + 1) >= 2)
		reverse_string(str+1);
	*(str + len - 1) = tmp;
}

主函数main()

int main()
{
	char arr[] = "abcdef";//fedcba
	reverse_string(arr);
	printf("%s\n", arr);
	return 0;
}

25.写一个递归函数DigitSum(n),输入一个非负整数,返回组成它的数字之和

int DigitSum(unsigned int n)
{
	if (n > 9)
	{
		return DigitSum(n / 10) + n % 10;
	}
	else
	{
		return n;
	}
}
int main()
{
	unsigned int num = 0;
	scanf("%d", &num);
	int ret = DigitSum(num);
	printf("%d\n", ret);
	return 0;
}

26.编写一个函数实现n的k次方,使用递归实现

//pow是内置函数的名字  不能重复
double Power(int n, int k)
{
	if (k > 0)
		return n * Power(n, k - 1);
	else if (k == 0)
		return 1;
	else
		return 1.0/Power(n, -k);
}
int main()
{
	int n = 0;
	int k = 0;
	scanf("%d %d", &n, &k);
	double ret = Power(n, k);
	printf("%lf\n", ret);
	return 0;
}

27.逗号表达式的数组大小

#include <stdio.h>
int main()
{
    int arr[] = { 1,2,(3,4),5 };
    printf("%d\n", sizeof(arr));   //16
    return 0;
}

28.区分sizeof( )和 strlen( )

#include <stdio.h>
#include <string.h>
int main()
{
    char str[] = "hello bit";  // [h e l l o _ b i t \0]
    printf("%d %d\n", sizeof(str), strlen(str));    //10  9
    char acX[] = "abcdefg";
    printf("%d %d\n", sizeof(acX), strlen(acX));    //8   7
    char acY[] = { 'a','b','c','d','e','f','g',};
    printf("%d %d\n", sizeof(acY), strlen(acY));    //7   23 这个23是随机值
    return 0;
}

29.创建一个整形数组,实现以下功能

void init(int arr[], int sz)   //实现函数init()初始化数组为全0
{
	int i = 0;
	for (i = 0; i < sz; i++)
	{
		arr[i] = 0;
	}
}

void print(int arr[], int sz)  //实现print()打印数组的每个元素
{
	int i = 0;
	for (i = 0; i < sz; i++)
	{
		printf("%d ", arr[i]);
	}
	printf("\n");
}

void reverse(int arr[],int sz) //实现reverse()函数完成数组元素的逆置
{
	int left = 0;
	int right = sz - 1;
	while (left < right)
	{
		int tmp = arr[left];
		arr[left] = arr[right];
		arr[right] = tmp;
		left++;
		right--;
	}
}

int main()
{
	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
	int sz = sizeof(arr) / sizeof(arr[0]);
	print(arr, sz);
	reverse(arr, sz);
	print(arr, sz);
	init(arr, sz);
	print(arr, sz);
	return 0;
}

30.将数组A中的内容和数组B中的内容进行交换(数组一样大)

int main()
{
	int arr1[] = { 1,3,5,7,9 };
	int arr2[] = { 2,4,6,8,0 };
	//arr3 = arr1;    //错误写法  数组不能直接交换
	//arr1 = arr2;
	//arr2 = arr3;
	int sz = sizeof(arr1) / sizeof(arr1[0]);
	int i = 0;
	for (i = 0; i < sz; i++)
	{
		int tmp = arr1[i];
		arr1[i] = arr2[i];
		arr2[i] = tmp;
	}
	return 0;
}

31.左移、右移操作符

int main()
{
	int a = 5;
	int b = a << 1;    
    printf("%d\n", a);  //5
    printf("%d\n", b);  //10
	return 0;
}
int main()
{
	int a = -5;
	int b = a << 1;
	printf("%d\n", a);    //5
	printf("%d\n", b);    //-10
	return 0;
}
int main()
{
	int a = -5;
	int b = a >> 1;
	printf("a=%d b=%d\n", a, b);  //-5  -3
	return 0;
}

32.按位与、按位或、按位异或

int main()
{
	int a = 3;
	int b = -5;
	int c = a & b;    //两个1才是1否则都是0  除不尽除2减一除的尽除二即可
	int d = a | b;    //两个0才是0否则都是1
	int e = a ^ b;      //对应的二进制位:相同为0,相异为1
	printf("c=%d d=%d e=%d\n", c,d,e);  //3  -5  -8
	return 0;
}

a^a = 0  0^a = a
对于多个数字进行异或计算后可以得知哪个数字只出现过一次
1 2 3 4 5 1 2 3 4  

33.不创建临时变量(第三个变量),实现两个数的交换

方法一

int main()    //方法一
{
	int a = 3;
	int b = 5;
	printf("a=%d b=%d\n", a, b);  
  int tmp = a;
  a = b;
  b = tmp;
	printf("a=%d b=%d\n", a, b);
	return 0;
}

方法二

int main()    //方法二  当数字超过内存最大值时会溢出
{
	int a = 3;
	int b = 5;
	printf("a=%d b=%d\n", a, b);  
	a = a + b;
	b = a - b;
	a = a - b;
	printf("a=%d b=%d\n", a, b);
	return 0;
}

方法三

int main()     //方法三  只能作用于整数互换
{
	int a = 3;
	int b = 5;
	printf("a=%d b=%d\n", a, b);  
	a = a ^ b;
	b = a ^ b;
	a = a ^ b;
	printf("a=%d b=%d\n", a, b);
	return 0;
}

34.编写代码实现:求一个整数存储在内存中的二进制中1的个数

5
00000000000000000000000000000101
00000000000000000000000000000001
5&1

int main()
{
	int num = 0;
	scanf("%d", &num);
	int i = 0;
	int count = 0;

	for (i = 0; i < 32; i++)
	{
		if (1 == ((num >> i) & 1))
		{
			count++;
		}
	}
	printf("%d\n", count);
	return 0;
}

35.C语言中C99之前没有表示真假的类型  C99中引用了布尔类型

#include <stdbool.h>
int main()
{
	_Bool flag1 = false;
	bool flag2 = true;
	if (flag2)
	{
		printf("hehe\n");
	}
	int num = 10;  //C语言中0表示假,非0表示真
	if (num)
	{

	}
	if (!num)//num为假,做事情
	{

	}
	return 0;
}

36.sizeof()

sizeof是一个操作符,不是函数,计算类型创建的变量所占内存的大小,单位是字节

int main()
{
	int a = 10;
	printf("%d\n", sizeof(a));    //4
	printf("%d\n", sizeof(int));  //4
	int arr[10] = { 0 };
	printf("%d\n", sizeof(arr));  //40
	return 0;
}
int main()
{
	int a = 10;
	short s = 0;
	printf("%d\n", sizeof(s = a + 2));  //sizeof()中的表达式不参与计算
	printf("%d\n", s);          //输出 2  0
	return 0;
}

37.按位取反~ 

{
	int a = 0;
	printf("%d\n", ~a);
	//00000000000000000000000000000000 - 0的原码
	//11111111111111111111111111111111 - 按位取反  这是补码
	//11111111111111111111111111111110 - 这是反码
	//10000000000000000000000000000001 ->这是原码  -1
	return 0;
}

38.把二进制里面的倒数的第三个数字0换做1 

int main()
{
	int a = 11;
    //方法一  按位或
	//00000000000000000000000000001011  把倒数的第三个数字0换做1 
    //00000000000000000000000000000100  这是4 
	//11111111111111111111111111111011
	//00000000000000000000000000000100  把数字1进行二进制左移两位得到4
	a |= (1<<2);         //实质就是a|= 4
	printf("%d\n", a);   //15
    //方法二  按位与
    //00000000000000000000000000001011  把倒数的第三个数字0换做1 
    //00000000000000000000000000000100  把数字1进行二进制左移两位得到4
    //11111111111111111111111111111011  对数字4进行按位取反得到
	a &= (~(1 << 2));
	printf("%d\n", a);   //11
	return 0;
}

39.++和--

int main()
{
	int a = 3;
	int b = ++a;//前置++,先++后使用  a=a+1,b=a
	int b = a++;//后置++,先使用后++  b=a,a=a+1
	int b = --a;//前置--,先--后使用  a=a-1,b=a
	int b = a--;//后置--,先使用再--  b=a,a=a-1
	printf("%d\n", b);
	return 0;
}

40.&&和| |

&& 一旦有假出现,后面的便不再运算

int main()
{
	int i = 0, a = 0, b = 2, c = 3, d = 4;
	i = a++ && ++b && d++;
    //&& 一旦有假出现,后面的便不再运算
	printf("a = %d\nb = %d\nc = %d\nd = %d\n", a, b, c, d);
	return 0;   //1 2 3 4
}

| | 一旦有真出现,后面的便不再运算

int main()
{
	int i = 0, a = 0, b = 2, c = 3, d = 4;
	i = a++ || ++b || d++;
    //|| 一旦有真出现,后面的便不再运算
	printf("a = %d\nb = %d\nc = %d\nd = %d\n", a, b, c, d);
	return 0;   //1 3 3 4
}

41.逗号表达式

int main()
{
	int a = 1;
	int b = 2;
	int c = (a > b, a = b + 10, a, b = a + 1);
	printf("a=%d b=%d\n", a, b);   //12  13
	printf("%d\n", c);             //13
	return 0;
}

42.输出数组指定元素

int main()
{
	int arr[10] = {1,2,3,4,5,6,7,8,9,10};
	printf("%d\n", arr[4]);
	printf("%d\n", 4[arr]);
	printf("%d\n", *(arr+4));
	printf("%d\n", *(4+arr));  //结果都是5
	return 0;
}

43.修改结构体内数据及调用输出

#include <string.h>
struct Stu
{
	char name[20];
	int age;
	float score;
}; 
void print1(struct Stu ss)    //结构体变量.成员名
{
	printf("%s %d %f\n", ss.name, ss.age, ss.score);
}
void print2(struct Stu* ps)   //结构体指针->成员名
{
	printf("%s %d %f\n", ps->name, ps->age, ps->score);
}
void print3(struct Stu* ps)
{
	printf("%s %d %f\n", (*ps).name, (*ps).age, (*ps).score);
}
int main()
{
	struct Stu s = {"张三", 20, 90.5f};
	strcpy(s.name, "张三丰");  //或者scanf("%s", s.name);都可以修改里面的数据
	print1(s);    //张三丰 20 90.500000
	print2(&s);   //张三丰 20 90.500000
	print3(&s);   //张三丰 20 90.500000
	return 0;
}

44.整体提升

int main()     //整体提升
{
	char c1 = 3;
	//00000000000000000000000000000011
	//00000011 - c1   //char只能放下八个字节  因此只保留八位
	char c2 = 127;
	//00000000000000000000000001111111
	//01111111 - c2
	char c3 = c1 + c2;
    //按照c1和c2在char里面存储的二进制数值的符号位进行部位
    //正数前面补0  负数前面补1
	//00000000000000000000000000000011 - c1
	//00000000000000000000000001111111 - c2
	//00000000000000000000000010000010 -再进行相加
	//10000010 - c3   最后只保留后面的八位
	//11111111111111111111111110000010  负数前面补1  得到存储的补码
	//11111111111111111111111110000001  减一得到反码
	//10000000000000000000000001111110  最后得到原码 -126
	printf("%d\n", c3);     //-126
	return 0;
}
int main()      //整体提升
{ 
	char a = 0xb6;//10110110
	short b = 0xb600;
	int c = 0xb6000000;
	if (a == 0xb6)
		printf("a");
	if (b == 0xb600)
		printf("b");
	if (c == 0xb6000000)
		printf("c");   //a和b都发生了整体提升,因此不输出,最后只输出c
	return 0;
}
int main()       //整体提升
{
	char c = 1;
	printf("%u\n", sizeof(c)); //1  算的是char类型的大小
	printf("%u\n", sizeof(+c));//4  由于进行了加减运算所以算的是int类型的大小
	printf("%u\n", sizeof(-c));//4  
	return 0;
}

45.求两个数二进制中不同位的个数

编程实现:两个int(32位)整数m和n的二进制表达中,有多少个位(bit)不同? 
思路:
1. 先将m和n进行按位异或,此时m和n相同的二进制比特位清零,不同的二进制比特位为1
2. 统计异或完成后结果的二进制比特位中有多少个1即可

#include <stdio.h>
int calc_diff_bit(int m, int n)
{
	int tmp = m ^ n;
	int count = 0;
	while (tmp)
	{
		tmp = tmp & (tmp - 1);
		count++;
	}
	return count;
}
int main()
{
	int m, n;
	while (scanf("%d %d", &m, &n) == 2)
	{
		printf("%d\n", calc_diff_bit(m, n));
	}
	return 0;
}

46.打印整数二进制的奇数位和偶数位

获取一个整数二进制序列中所有的偶数位和奇数位,分别打印出二进制序列

思路:提取所有的奇数位,如果该位是1,输出1,是0则输出0。以同样的方式提取偶数位置

检测num中某一位是0还是1的方式:
1. 将num向右移动i位
2. 将移完位之后的结果与1按位与,如果:结果是0,则第i个比特位是0,结果是非0,则第i个比特位是1。

void Printbit(int num)
{
	for (int i = 31; i >= 1; i -= 2)
	{
		printf("%d ", (num >> i) & 1);
	}
	printf("\n");

	for (int i = 30; i >= 0; i -= 2)
	{
		printf("%d ", (num >> i) & 1);
	}
	printf("\n");
}
int main()
{
	int num = 0;
	printf("请输入一个数: ");
	scanf("%d", &num);
	Printbit(num);
	return 0;
}

47.统计二进制中1的个数

#include<stdio.h>
int Hamming_weight_2(int number)  //只考虑1的位数
{
    int count_ = 0; //声明计数变量
    while (number != 0)  //遍历
    {
        number &= number - 1;
        count_++;
    }
    return count_;
}
int main()
{
    int n;
    while (scanf("%d", &n) != EOF)  //读入整数和打印1的个数
    {
        printf("%d \n", Hamming_weight_2(n));
    }
    return 0;
}

方法一:
思路:
循环进行以下操作,直到n被缩减为0:
   1. 用该数据模2,检测其是否能够被2整除
   2. 可以:则该数据对应二进制比特位的最低位一定是0,否则是1,如果是1给计数加1
   3. 如果n不等于0时,继续1

缺陷:进行了大量的取模以及除法运算,取模和除法运算的效率本来就比较低。

int count_one_bit(int n)
{
	int count = 0;
	while (n)
	{
		if (n % 2 == 1)
			count++;
		n = n / 2;
	}
	return count;
}

方法二:
思路:一个int类型的数据,对应的二进制一共有32个比特位,可以采用位运算的方式一位一位的检测

优点:用位操作代替取模和除法运算,效率稍微比较高
缺陷:不论是什么数据,循环都要执行32次

int count_one_bit(unsigned int n)
{
	int count = 0;
	int i = 0;
	for (i = 0; i < 32; i++)
	{
		if (((n >> i) & 1) == 1)
			count++;
	}
	return count;
}

方法三:
思路:采用相邻的两个数据进行按位与运算
举例:
9999:‭10 0111 0000 1111‬
第一次循环:n=9999   n=n&(n-1)=9999&9998= 9998
第二次循环:n=9998   n=n&(n-1)=9998&9997= 9996
第三次循环:n=9996   n=n&(n-1)=9996&9995= 9992
第四次循环:n=9992   n=n&(n-1)=9992&9991= 9984
第五次循环:n=9984   n=n&(n-1)=9984&9983= 9728
第六次循环:n=9728   n=n&(n-1)=9728&9727= 9216
第七次循环:n=9216   n=n&(n-1)=9216&9215= 8192
第八次循环:n=8192   n=n&(n-1)=8192&8191= 0
可以观察到:此种方式,数据的二进制比特位中有几个1,循环就循环几次,而且中间采用了位运算,处理起来比较高效

int count_one_bit(int n)
{
	int count = 0;
	while (n)
	{
		n = n & (n - 1);
		count++;
	}
	return count;
}

48.求代码输出结果

#include <stdio.h>
int main()
{
    int arr[] = { 1,2,3,4,5 };
    short* p = (short*)arr;
    int i = 0;
    for (i = 0; i < 4; i++)
    {
        *(p + i) = 0;
    }

    for (i = 0; i < 5; i++)
    {
        printf("%d ", arr[i]);
    }
    return 0;
}

解析:
arr数组在内存中的存储格式为:
0x00ECFBF4:  01 00 00 00
0x00ECFBF8 : 02 00 00 00
0x00ECFBFC : 03 00 00 00
0x00ECFC00 : 04 00 00 00
0x00ECFC04 : 05 00 00 00
指针p的类型为short * 类型的,
 因此p每次只能所有两个字节,for循环对数组中内容进行修改时,一次访问的是:
arr[0]的低两个字节,arr[0]的高两个字节,arr[1]的低两个字节,
arr[1]的高两个字节,
故改变之后,数组中内容如下:
0x00ECFBF4 : 00 00 00 00
0x00ECFBF8 : 00 00 00 00
0x00ECFBFC : 03 00 00 00
0x00ECFC00 : 04 00 00 00
0x00ECFC04 : 05 00 00 00
故最后打印:0   0   3   4   5

unsigned long pulArray[] = { 6,7,8,9,10 };
unsigned long* pulPtr;
pulPtr = pulArray;
*(pulPtr + 3) += 3;
printf(“% d, % d\n”, *pulPtr, *(pulPtr + 3));

unsigned long pulArray[] = { 6,7,8,9,10 };
unsigned long* pulPtr;
pulPtr = pulArray; 
数组名代表数组首元素地址,因此pulptr指向的是数组中第一个元素的位置
*(pulPtr + 3) += 3; 
pulptr+3访问的是数组中第三个元素(数组下标从0开始),故将9改为9+3=12
printf(“% d, % d\n”, *pulPtr, *(pulPtr + 3)); 
打印第一个和第三个元素,因此:打印6和12

#include <stdio.h>
int main()
{
    int a = 0x11223344;
    char* pc = (char*)&a;
    *pc = 0;
    printf("%x\n", a);
    return 0;
}

假设,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

49.写一个函数打印arr数组的内容,不使用数组下标,使用指针

#include <stdio.h>
int main()
{
    int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
//分析:因为数组中存储的元素类型是int类型的,因此只要给一个int的指针依次取索引数组中的每个元素即可
    int* p = arr;  // 数组名代表数组首元素的地址
    for (int i = 0; i < sizeof(arr) / sizeof(arr[0]); ++i)
    {
        printf("%d ", *p);   // *p: 取到p所指向位置的元素
        ++p;                 // 获取p的下一个位置
    }
    return 0;
}

50.求出0~100000之间“水仙花数”,打印菱形

“水仙花数”是指一个n位数,其各位数字的n次方之和确好等于该数本身,
如:153=1 ^ 3+5 ^ 3+3 ^ 3,则153是一个“水仙花数”。

#include <stdio.h>
#include <math.h>
int main()
{
	int i = 0;
	for (i = 1; i <= 99999; i++)
	{
		int tmp = i;//各位数
		int count = 0;//n
		int sum = 0;
		while (tmp)
		{
			tmp /= 10;//各位数
			count++;
		}
		tmp = i;
		while (tmp)
		{
			sum += pow((tmp % 10), count);
			tmp /= 10;
		}
		if (sum == i)
		{
			printf("%d是水仙花数\n", i);
		}
	}
	return 0;
}
#include<stdio.h>
#include<stdlib.h>
void PrintLine(int blank_count, int start_count) 
{
	int i = 0;
	for (; i < blank_count; i++) 
	{
		printf(" ");  //打印空格
	}
	for (i = 0; i < start_count; i++) 
	{
		printf("*");
	}
	printf("\n");
}
void  PrintLingxing(int n) 
{
	//打印上半部分
	int i = 1;
	for (i = 1; i < n; i++) 
	{
		PrintLine(n - i, 2 * i - 1);  // 打印每一行的空格和每一行的星号
	}
	//打印中间部分
	PrintLine(0, 2 * n - 1);
	//打印下半部分
	for (i = n - 1; i > 0; i--) 
	{
		PrintLine(n - i, 2 * i - 1);
	}
}
int main() 
{
	PrintLingxing(7);    //对半的行数
	system("pause");
	return 0;
}

      *
     ***
    *****
   *******
  *********
 ***********
*************
 ***********
  *********
   *******
    *****
     ***
      *

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值