C语言学习记录—作业8

1. 下方程序输出结果

int main()
{
	int arr[] = { 1, 2, 3, 4, 5 };
	short* p = (short*)arr;//shor*指针一次能访问两个字节。+1一次跳过两个字节
	//0x 00 00 00 01 - 1的十六进制
	//0x 00 00 00 02 - 2的十六进制
	//0x 00 00 00 03 - 3的十六进制
	//0x 00 00 00 04 - 4的十六进制
	//0x 00 00 00 05 - 5的十六进制
	//数据在内存中存放的时候,有一个顺序问题。大小端字节序。实际存放情况如下:
	//01 00 00 00 02 00 00 00 03 00 00 00 04 00 00 00 05 00 00 00
	//左边是低地址,右边是高地址
	//因为int类型是四个字节,short*指针一次访问两个字节,
	//所以下方循环4次,总共改了8个字节,即前两个整数
	int i = 0;
	for (i = 0; i < 4; i++)
	{
		*(p + i) = 0;
	}

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

	return 0;
}

2. 下方程序输出结果

int main()
{
	unsigned long pulArray[] = { 6,7,8,9,10 };
	unsigned long* pulPtr;
	pulPtr = pulArray;
	*(pulPtr + 3) += 3;//下标为3的元素在加3
	printf("%d, %d\n", *pulPtr, *(pulPtr + 3));//6 12
	return 0;
}

3. 下方程序输出结果

同第一题一样,0x11223344在内存顺序是44332211。因为修改了第一个字节,所以修改了44为00

int main()
{
	int a = 0x11223344;
	char* pc = (char*)&a;
	*pc = 0;
	printf("%x\n", a);//0x11223300
	//任何一个变量或表达式都有2个属性:值属性;类型属性
	//int a = 3;
	//a + 4.5 -> 7.5(值属性)
	//类型属性:double
	//a的值是3,类型属性是int。 &a的类型属性是int*,a的值属性就是地址
	return 0;
}

4. 使用指针打印数组内容

void print(int* p, int sz)
{
	int i = 0;
	for (i = 0; i < sz; i++)
	{
		printf("%d ", *(p + i));
	}
	printf("\n");
}
int main()
{
	int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
	int sz = sizeof(arr) / sizeof(arr[0]);
	print(arr, sz);
	return 0;
}

5. 将一个字符串str的内容颠倒过来,并输出。

#include <string.h>
int main() 
{
    char arr[10001] = {0};//加1是为了放下\0
    //scanf("%s", &arr);//scanf遇到空格就不读取了
    gets(arr);

    int left = 0;//从下标0开始
    int right = strlen(arr) - 1;

    while (left < right) 
    {
        char tmp = arr[left];
        arr[left] = arr[right];
        arr[right] = tmp;
        left++;
        right--;
    }
    printf("%s\n", arr);

    return 0;
}

6. 计算求和

求Sn = a + aa + aaa + aaaa + aaaaa的前5项之和,
其中a是一个数字例如 : 2 + 22 + 222 + 2222 + 22222

//2
//2*10+2 = 22
//22*10+2 = 222
//222*10+2 = 2222
int main()
{
	int a = 0;
	int n = 0;
	scanf("%d %d", &a, &n);

	int sum = 0;
	int k = 0;//每一项

	int i = 0;
	for (i = 0; i < n; i++)
	{
		k = k * 10 + a;
		sum += k;
	}
	printf("%d\n", sum);
	return 0;
}

7. 求出1 ~ 10009之间的所有“水仙花数”并输出。

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

非函数版本
#include <math.h>int main()
{
	int i = 0;
	for (i = 0; i <= 100000; i++)//判断i是否为水仙花数
	{
		//1234
		//1234/10=123 1位
		//123/10=12   2位
		//12/10=1     3位
		//1/10=0      4位
		//1. 计算i是几位数 -> n
		int n = 1;//任何一个数至少是一位数

		//下方有一个问题,i不停除以10直到等于0,但是上方又是遍历i,i要++。所以矛盾了
		//这里是典型的循环内部改变循环变量,所以需要一个临时变量来存放i,这样就可以不修改i变量
		int tmp = i;
		int sum = 0;//sum不能创建在循环外面,因为每一个i都要求和验证,所以每次都要从0开始
		while (tmp / 10)
		{
			n++;//如果i/10不等于0,位数就加1
			tmp /= 10;
		}
		//2. 得到i的每一位,计算他的n次方之和
		//上方经过循环,每次tmp最后都等于0,所以再次把i放到临时变量中,得到i的每一位
		tmp = i;
		//1234%10=4
		//1234/10=123
		//123%10=3
		//123/10=12
		//通过上述方法得到每一位的数,直到tmp变成0说明所有位都取出
		while (tmp)
		{
			sum += pow(tmp % 10, n);//得到每一位,在计算它的n(位数)次方;即某一位的位数的次方
			tmp /= 10;//算完某一位的次方后,再去掉那一位
		}
		if (sum == i)//判断每一位 位数次方的和是否等于它本身
		{
			printf("%d ", i);
		}

	}
	return 0;
}

函数版本
//函数版本
int is_narcissistic_number(int i)
{
	int n = 1;
	//1. 计算i是几位数 -> n
	int tmp = i;
	int sum = 0;
	while (tmp / 10)
	{
		n++;
		tmp /= 10;
	}
	//2. 得到i的每一位,计算他的n次方之和
	tmp = i;
	while (tmp)
	{
		sum += pow(tmp % 10, n);//得到每一位,在计算它的n(位数)次方;即某一位的位数的次方
		tmp /= 10;//算完某一位的次方后,再去掉那一位
	}

	return sum == i;//等效下方,如果sum等于i,表达式为真,返回1;如果不等于表达式为假,返回0
	//if (sum == i)//判断每一位 位数次方的和是否等于它本身
	//	return 1;
	//else
	//	return 0;

}
int main()
{
	int i = 0;
	for (i = 0; i <= 100000; i++)//判断i是否为水仙花数
	{
		if (is_narcissistic_number(i))
		{
			printf("%d ", i);
		}
	}
	return 0;
}

8. 打印菱形

思路:分上下两个部分(上半部到第7行,即最多那一行)。上半部空格在减少,星星在增多;下半部分空格增多,星星减少

int main()
{
	int line = 0;
	scanf("%d", &line);
	//上 - 上半部分是line行
	int i = 0;
	for (i = 0; i < line; i++)//上半部分的打印
	{
		//上半部每一行的打印,分为空格和*
		//空格的打印 - 随着行的增长,空格数量减少。假设有7行,第一行有6个空格,依次减少。第7行没空格
		int j = 0;
        //line-1表示只有6行有空格。随着行数增加1,空格减少1,所以减去行数
		for (j = 0; j < line - 1 - i; j++)
		{
			printf(" ");
		}
		//*的打印 - *和行的关系是2*i+1就是每行*的数量,i第一次等于0
		for (j = 0; j < 2 * i + 1; j++)
		{
			printf("*");
		}
		printf("\n");
	}
	//下 - 下半部分是line-1行,最终打印的行数是2*line-1行
	for (i = 0; i < line - 1; i++)//下半部分的打印
	{
		//打印一行
		//下半部空格打印 - 随着行数增长,空格数量增加,第几行就有几个空格
		int j = 0;
		for (j = 0; j <= i; j++)
		{
			printf(" ");
		}
		//*的打印 - *和行的关系是,假设有6行,第一行是2*6-1,第二行是2*5-1
		for (j = 0; j < 2*(line-1-i)-1; j++)
		{
			printf("*");
		}
		printf("\n");
	}
	return 0;
}

9. 下面程序要求输出结构体中成员a的数据,以下不能填入横线处的内容是()

//A a.a
//B *p.a - 此为错误选项,p是结构体指针,不能用.操作符
//C p->a
//D (*p).a	*p解引用找到了结构体变量a,和A选项一样
struct S
{
	int a;
	int b;
};
int main()
{
	struct S a, *p = &a;//这里还有一个结构体指针变量struct S* p = &a;
	
	a.a = 99;
	printf("%d\n", ________);
	return 0;
}

10. 下面程序输出结果

struct stu
{
	int num;
	char name[10];
	int age;
};
void fun(struct stu* p)
{
	printf("%s\n", (*p).name);
	return;
}
int main()
{
	//students是数组
	struct stu students[3] = {
		{9801, "zhang", 20},
		{9802, "wang", 19},
		{9803, "zhao", 18}
	};
	fun(students + 1);//这里的students数组名就是地址
	return 0;
	//结果是 wang
}

11. 喝汽水,1瓶汽水1元,2个空瓶可以换一瓶汽水,给20元,可以多少汽水(编程实现)。

思路:

1. 买了20瓶,有20个空瓶,换10瓶汽水
2. 10个空瓶再换5瓶汽水
3. 5个空瓶换2瓶汽水,还剩余1空瓶
4. 2瓶汽水喝完,总共有2+1(这个是上次剩下的)空瓶
5. 3个空瓶换了1瓶汽水,还剩1个空瓶,喝的加剩下的1个空瓶,总共有2个空瓶
6. 2个空瓶换1瓶汽水,此时只有1个瓶子,换不了,结束

int main()
{
	//方法一
	//三个变量
	//钱money -> 输入的
	//喝的总瓶数total,刚开始等于money
	//空瓶empty,一开始也等于money
	//接下来置换,条件是empty>=2
	int money = 0;
	scanf("%d", &money);
	int total = money;
	int empty = money;

	//置换
	while (empty >= 2)
	{
		//empty/2是置换到的汽水,置换到的喝了以后加到已经喝了的总数里
		total += empty / 2;

		//empty是喝完以后,当前手里的总空瓶数。
		//empty/2既是能置换到的汽水,也是下次能获得的空瓶数。除去已经拿去置换的空瓶,还要加上手里不足以置换的空瓶数
		empty = empty / 2 + empty % 2;
	}
	printf("%d\n", total);


	//方法二
	if (money > 0)
		printf("%d\n", 2 * money - 1);
	else
		printf("%d\n", 0);
	return 0;
}


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值