C语言刷题日记(附详解)(1)

news2024/9/22 23:38:48

一、选择判断部分

第一题:

如下代码是否存在风险,并说明原因和修改方案

#include<stdio.h>
int main()
{
	char* str = "hello world";
	*str = 'a';
	return 0;
}

思路提示:这种形式的字符串存储在什么区域呢?是否真的有写入权限?

答案:运行会报错!!!

因为这种形式的字符串是存储在常量区的,而对于储存在常量区的数据只能进行读取,并不能进行写入,所以此时直接对str所指向的值进行修改是不行的。当然,如果我们先将字符串存放在数组形式中,就可以对数据进行修改啦:

#include<stdio.h>
int main()
{
	char str[] = "hello world";
	char* pstr = str;
	*str = 'a';
	return 0;
}

第二题:

若定义:int a[2][3]={1,3,5,7,9,11},以下描述正确的是(      )

A:*(a + 1)为元素7的地址

B:(a[1] + 1)的值是5

C:**(a + 1) + 2值是11

D:a[0]和a不同

答案:A

题解:在二维数组中,*(a + 1)代表的是第二列首元素的地址,而第二列首元素对应的值为7,则A是正确的。而(a[1] + 1)所代表的是第二列的第二个元素的地址,对应的值应该为9的地址(需要再解引用一次才是9),故B是错误的。**(a + 1) + 2中**(a + 1)所代表的是第二列首元素,此值为7,+2得9,并不是11,所以C是错误的。a所代表的是首元素地址,也就是数组首地址,而a[0]代表的是第一列的首元素地址,同样也是数组首地址,故a和a[0]其实是相同的。

第三题:

请问下列代码的输出是多少 (      )

#include<stdio.h>
int main()
{
	int m[] = { 1,2,3,4,5,6,7,8,9,0 };
	int(*p)[4] = (int(*)[4])m;
	printf("%d", p[1][2]);
	return 0;
}

思路提示:int(*p)[n]代表的是什么?而int* p[n]代表的又是什么?p[1][2]中p这个二维数组是对一维数组m以什么形式的拆分所得到的呢?

答案:输出结果是7。

题解:int∗ p[n] 表示的是大小为n的,用来存储指针变量的指针数组
           int(∗p)[n] 表示的是一个指向有n个元素的数组的
数组指针

而对于(int(*)[4])m, 我们可以联想一下:(int)m 就是将m强制类型转换为int型,而此时(int(*)[4])m也与(int)m的格式相似,而(int(*)[4])的格式代表了一个以4位元素组成一组的数组指针,此时将m强制类型转换为它,那么m现在就应该是{{1,2,3,4},{5,6,7,8},{9,0, , }};而p[1][2]所指向的就是第二列的第三个元素也就是7

第四题:

说出以下代码的错误之处,并说明原因:

char* getmemory(void)
{
	char p[] = "hello world";
	return p;
}
void test()
{
	char* str = NULL;
	str = getmemory();
	printf("%s", str);
}
int main()
{
	test();
	return 0;
}

思路提示:在getmemory函数中定义的p值在什么区域?是全局变量?还是局部变量?还是静态变量?

答案:运行不报错,但也不会输出hello world,而是随机输出乱码。

题解:因为当我们将str置空之后,将str传入getmemory函数中,虽然getmemory函数中期望的定义并返回的p为hello world,但p是一个局部变量,当退出函数时,p会自动销毁,而此时我们再打印str时,会发现str不再是NULL了,但也不会是hello world,而是随机的乱码。

第五题:

请问下列代码的输出是什么(      )

int main() 
{
    char* str = "hello.com";
    int i;
    str = "hello world!";
    int len = strlen(str);
    printf("%d \n", len);
    printf("%c \n", *(str + 4));
    printf("%s \n", (str + 6));
    return 0;
}

答案

12
o
world!

题解:因为将str重新赋值后长度发生了改变,此时长度为12,*(str + 4)对应的是str字符数组中第五个字符,也就是o,而打印字符串形式(str + 6)代表的就是跳过str前六个字符再进行打印,也就是world!。

二、编程题部分

第一题:统计字母,空格,字符数!

输入一行字符,分别统计出其中英文字母、空格、数字和其它字符的个数。

输入样例:

aaabbb11223344   @@@@

输出样例:

数字个数为:8
字母个数为:6
空格个数为:3
字符个数为:4

思路提示:想要做到分别统计出一段字符中的英文字母,空格,数字以及其他字符个数,我们可以定义出四个计数器,分别来统计数字,字母,空格,字符的个数。然后我们可以定义一个整型变量sz用来存放这段字符的长度通过一个for循环将这段字符的每一个字符遍历一边,并且对每一个字符进行判断,使相应的计数器自增,最后按格式输出它们的个数。

答案

int main()
{
	char arr[100];
	fgets(arr, 100, stdin);
	int sz = strlen(arr) - 1;
	int shunum = 0;
	int zinum = 0;
	int kongnum = 0;
	int funum = 0;
	int i = 0;
	for (i = 0; i < sz; i++)
	{
		if (arr[i] >= '0' && arr[i] <= '9')
			shunum++;
		else if ((arr[i] >= 'a' && arr[i] <= 'z') || (arr[i] >= 'A' && arr[i] <= 'Z'))
			zinum++;
		else if (arr[i] == ' ')
			kongnum++;
		else
			funum++;
	}
	printf("数字个数为:%d\n", shunum);
	printf("字母个数为:%d\n", zinum);
	printf("空格个数为:%d\n", kongnum);
	printf("字符个数为:%d\n", funum);
	return 0;
}

需要注意的是:在对定义的字符串赋值时,我们使用的是fgets函数而并非scanf("%s"),这是因为使用scanf的形式进行赋值,在遇到空格时会终止赋值,所以无法判断空格的个数。而fgets函数在进行赋值时,大部分情况下不会被终止只有遇到换行符号"\n",或者已经达到输入大小的限度才会终止

由图我们可以知道,fgets函数的原型,以及fgets传参的参数类型。

char* fgets(char* str, int num, FILE* stream)

第一个参数char* str代表的是:容器的地址

第二个参数int num代表的是:容器的大小

第三个参数FILE* stream代表的是:从哪里开始读取

在题中我们使用的格式为fgets(arr, 100, stdin);这段代码就代表,我们需要为地址为arr的容器进行赋值,并且容器最大为100,从0(键盘)开始读取。(stdin代表输入流,表示从0(键盘)开始记录)

第二题:然后是几点?

我们使用四个数字来代表时间,比如1209代表12点零9分。而此题中,你的代码需要计算之前的时间加上经过的时间后的到的现在的时间

读入两个数字,一个数字代表之前的时间,另一个数字代表经过的时间,而最后输出现在的时间。比如我们输入:1130 160;   输出:1410;

思路提示:如果直接将时间用一个数来表示,那么将本是100进1的小时位改成60进1的小时位未免过于繁琐,我们是否可以尝试一下将时间分成两个数字分别代表小时和分钟呢?这样或许会方便很多哦~

答案

int main()
{
	int time;
	int minute;
	scanf("%d %d", &time, &minute);
	int time1 = time / 100;//用来表示小时
	int time2 = time % 100;//用来表示分钟
	if (minute > 0)//用来判断经过时间>0
	{
		while (minute > 60)
		{
			time1++;
			minute -= 60;
		}
	}
	else if (minute < 0)//用来判断经过时间<0
	{
		while (minute < 0)
		{
			time1--;
			minute += 60;
		}
	}
	time2 += minute;
	if (time2 >= 60)//将>60的分钟进位
	{
		time1++;
		time2 -= 60;
	}
	if (time1 > 24)
		time1 -= 24;
	if(time2<10)//补充分钟为个位时,中间缺少的0
		printf("%d0%d", time1, time2);
	else
		printf("%d%d", time1, time2);
	return 0;
}

题解我们定义两个变量为time1time2time1 = time / 100;代表只取两个高位数,也就是小时而time2 = time % 100;代表只取两个低位数,也就是分钟。之后我们使用if选择语句和while循环语句,将流逝的时间minute分别加在小时位和分钟位上当minute>60时,不断地将minute自减60,并且同时为小时位+1同时也要注意,此题中输入流逝时间为负数的情况(难道这就是传说中的反方向的钟?!)同样的当minute<0时,不断地将minute自增60,并且同时小时位-1。最后将剩余的时间加在分钟位上,再进行一次time2是否>=60的判断,然后此题就解决啦~怎么样,只要想到将小时和分钟分开算,其实还是很简单的呢。

第三题:阶乘计算升级版

本题要求实现一个打印非负整数的阶乘的函数

要求其中N是用户传入的参数,其值不超过1000。如果N是非负整数,则该函数必须在一行中打印出N!的值,否则打印“Invalid input”

整体代码:

#include <stdio.h>

void Print_Factorial(const int N)
{
    /* 你需要编写并实现此代码 */


}

int main()
{
    int N;

    scanf("%d", &N);
    Print_Factorial(N);
    return 0;
}

思路提示:平时我们使用的阶乘计算方法很简单,比如我们此时要求5!,只需要定义一个整形变量初始化值为1,for(i=1;i<=5;i++),使此变量在for循环中与i分别相乘,就能求出5!

int main()//阶乘计算初阶版
{
	int a;
	scanf("%d", &a);
	int i = 0;
	int sum = 1;
	for (i = 1; i <= a; i++)
	{
		sum *= i;
	}
	printf("%d", sum);
	return 0;
}

但这是之前的初阶版,对于比较小的数字求阶乘还勉强能做到,但如果要求的阶乘位数很高呢,高到我们用long long型变量也接收不了,那该怎么办呢?给大家一个提示:我们可以定义一个很大的数组,用数组中的元素分别放置阶乘结果的每一位数字,这样无论结果位数多大,我们也能轻松自如的接收啦~

(在此大家可能觉得,就算知道了用数组接收每一位数字的思路,但想要实现能够计算1000!的函数还是太难太繁琐了,确实这是一个较难的题(也可能是我菜(ㄒoㄒ)),那让我们先做一个稍微比较好理解的题来练练手吧~)

练手题:大数加法

利用数组的形式存储每一位数字并进行运算。

运行效果:

大数加法的核心思想与阶乘计算升级版的思想是一致的,我们需要使用数组来接收每一位数字并运算。因为是大数加法,所以输入的数字也可能非常大,所以输入的数字也需要使用数组来存储

因为我们需要使每一位数字存储在数组相应的位置,并且这一位数字必须是个位数,所以我们可以将其转换成字符形式这样输入运算数时,自动就将每一位运算数当作字符存储在相应位置了~~~那么有了思路,具体来操作一下:我们定义三个char型数组,char a[10001]用来接收大数运算数(存入时为字符类型),char arr1[10001]和char arr2[10001]用来接收两个大数运算数(接收时将每一位都转换成数字类型)

char a[10001] = { 0 };//用于存储运算数(字符形式)
char arr1[10001] = { 0 };//用于接收运算数(接收需转换成数字形式)
char arr2[10001] = { 0 };//用于接收运算数(接收需转换成数字形式)
printf("输入两个运算数:\n");
scanf("%s", a);
for (i = strlen(a) - 1; i >= 0; i--)
{
	arr1[tmp++] = a[i] - '0';//将字符转换为数字
}
scanf("%s", a);
for (tmp = 0,i = strlen(a) - 1; i >= 0; i--)
{
	arr2[tmp++] = a[i] - '0';//将字符转换为数字
}

解决了大数运算数的传输与接收,那么再让我们来思考一下,大数运算数如何通过数组的形式进行每一位的运算呢

让我们来举一个例子,并且逐步分析,来看一下运算的过程

比如此时我们输入的arr1为97,输入的arr2为75,那么两者运算过程就会是:

 个 十 百
 7  9  0
 5  7  0
 (第一次运算)
 tmp = arr1[i] + arr2[i] + up; (tmp = 7 + 5 + 0 = 12)
 arr1[i] = tmp % 10; (arr1[i] = 12 % 10 = 2)
 up = tmp / 10;  (up = 12 / 10 = 1)
 (第二次运算)
 tmp = arr1[i] + arr2[i] + up; (tmp = 9 + 7 + 1 = 17)
 arr1[i] = tmp % 10; (arr1[i] = 17 % 10 = 7)
 up = tmp / 10;  (up = 17 / 10 = 1)
 (第三次运算)
 tmp = arr1[i] + arr2[i] + up; (tmp = 0 + 0 + 1 = 1)
 arr1[i] = tmp % 10; (arr1[i] = 1 % 10 = 1)
 up = tmp / 10;  (up = 1 / 10 = 0)
 (结束运算)
 结果为:
 arr1[0] = 2 arr1[1] = 7 arr1[2] = 1;(97 + 75 = 172)

由此,我们就能够直观的看出运算过程到底是何种方式~我们可以定义两个整型变量tmp和up来辅助运算,tmp代表此次两个位数相加的和up代表两个位数相加后是否需要进1而arr1[i]用来存储此次运算后得到的此位数字(只需要取10的余数即可)。将这个思路转化为运算公式的形式就会是这样:

for (i = 0; i < 10000/*运算的最大位数*/; i++)
{
	tmp = arr1[i] + arr2[i] + up;//两数相加运算
	arr1[i] = tmp % 10;
	up = tmp / 10;
}

怎么样?转化为运算公式之后,是不是感觉一下简便了很多呢~接下来就只剩下最后的打印工作了此处我们需要注意的是,之前我们对arr1和arr2进行存储时,使用的是逆序的存储,这样的目的是使低位数在前,高位数在后,这样我们就能做到使用for循环运算时先计算低位数,再计算高位数相应的,得出的结果也理所当然的是逆序,所以打印时我们需要从后往前打印,才能得出真正的结果~

答案

int main()
{
	char a[10001] = { 0 };//用于存储运算数(字符形式)
	char arr1[10001] = { 0 };//用于接收运算数(接收需转换成数字形式)
	char arr2[10001] = { 0 };//用于接收运算数(接收需转换成数字形式)
	int tmp = 0;
	int up = 0;
	int i = 0;
	printf("输入两个运算数:\n");
	scanf("%s", a);
	for (i = strlen(a) - 1; i >= 0; i--)
	{
		arr1[tmp++] = a[i] - '0';//将字符转换为数字
	}
	scanf("%s", a);
	for (tmp = 0,i = strlen(a) - 1; i >= 0; i--)
	{
		arr2[tmp++] = a[i] - '0';//将字符转换为数字
	}
	printf("运算结果为:\n");
	for (i = 0; i < 10000; i++)
	{
		tmp = arr1[i] + arr2[i] + up;//两数相加运算
		arr1[i] = tmp % 10;
		up = tmp / 10;
	}
	for (i = 10000; i >= 0; i--)
	{
		if(arr1[i]!=0)
			for(i;i>=0;i--)//逆序打印出真正结果
		printf("%d", arr1[i]);
	}
	return 0;
}

那么学会了大数相加,让我们收回思路,继续解决阶乘计算升级版吧~

还是同样的思路,我们需要定义一个足够大的char型数组用来后续存放i的阶乘,然后先分别对<0求阶乘和对0,对1求阶乘的情况进行解决:

#include <stdio.h>
void Print_Factorial(const int N)
{
    char a[5000] = { 1 };//因为是相乘而不是相加,如果初始化为0则无法进行相乘
    int tmp = 0;         //所以我们将第一个元素初始化为1,使其能够正常运算
    int i = 0;           //并且其他的元素仍为0,使用进位来增大其余元素
    int j = 0;
    int up = 0;
    if (N < 0)
        printf("Invalid input");
    else if (N == 0 || N == 1)
        printf("1");
    else
    {
        ...
    }

而else中的内容,就是求阶乘的运算了~

同样的,让我们举个例子,逐步分析一下应该如何运算:

 从 i = 2 开始 i<=5 i++ 分别求2! 3! 4! 5!
 (计算2!)//2 0 0
 tmp = a[j] * i + up; (tmp = 1 * 2 + 0 = 2)
 a[j] = tmp % 10; (a[j] = 2 % 10 = 2)
 up = tmp / 10; (up = 2 / 10 = 0)
 (计算3!)//6 0 0
 tmp = a[j] * i + up; (tmp = 2 * 3 + 0 = 6)
 a[j] = tmp % 10; (a[j] = 6 % 10 = 6)
 up = tmp / 10; (up = 6 / 10 = 0)
 (计算4!)//4 2 0(逆序)
 tmp = a[j] * i + up; (tmp = 6 * 4 + 0 = 24)
 a[j] = tmp % 10; (a[j] = 24 % 10 = 4)
 up = tmp / 10; (up = 24 / 10 = 2)
 tmp = a[j] * i + up; (tmp = 0 * 4 + 2 = 2)
 a[j] = tmp % 10; (a[j] = 2 % 10 = 2)
 up = tmp / 10; (up = 2 / 10 = 0)
 (计算5!)//0 2 1(逆序)
 tmp = a[j] * i + up; (tmp = 24 * 5 + 0 = 120)
 a[j] = tmp % 10; (a[j] = 120 % 10 = 0)
 up = tmp / 10; (up = 120 / 10 = 12)
 tmp = a[j] * i + up; (tmp = 0 * 5 + 12 = 12)
 a[j] = tmp % 10; (a[j] = 12 % 10 = 2)
 up = tmp / 10; (up = 12 / 10 = 1)
 tmp = a[j] * i + up; (tmp = 0 * 5 + 1 = 1)
 a[j] = tmp % 10; (a[j] = 1 % 10 = 1)
 up = tmp / 10; (up = 1 / 10 = 0)

(整理这个真的要把我这个小菜鸡累毁了!!!各位看到这里如果不介意的话,点点收藏点点赞吧 T A T)

统计成公式就是:

for (i = 2; i <= N; i++)
{
    for (up = 0, j = 0; j <= 5000; j++)
    {
        tmp = a[j] * i + up;
        a[j] = tmp % 10;
        up = tmp / 10;
    }
}

最后我们只需要将运算出来的数组给逆序打印出来就好啦~

答案

#include <stdio.h>
void Print_Factorial(const int N)
{
    char a[5000] = { 1 };
    int tmp = 0;
    int i = 0;
    int j = 0;
    int up = 0;
    if (N < 0)
        printf("Invalid input");
    else if (N == 0 || N == 1)
        printf("1");
    else
    {
        for (i = 2; i <= N; i++)
        {
            for (up = 0, j = 0; j <= 5000; j++)
            {
                tmp = a[j] * i + up;
                a[j] = tmp % 10;
                up = tmp / 10;
            }
        }
        for (i = 5000; i >= 0; i--)
        {
            if (a[i] != 0)
                for (i; i >= 0; i--)
                    printf("%d", a[i]);
        }
    }
}
int main()
{
    int N;
    scanf("%d", &N);
    Print_Factorial(N);
    return 0;
}

怎么样,是不是看起来比大数运算还要更加简便一些呢?但其实这段乘法的公式是真的难!!

最后我们算出1000的阶乘为......好可怕的数字......不愧是计算机,这都能算出来~

那么今天的刷题日记就给大家分享到这啦~如果有哪里说的不对的或者讲解的不清楚的,还请大家多多在评论区指出意见哦~我也会多多吸取教训,多多学习的~那么我们下一篇再见啦ヾ(•ω•`)o

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2054206.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【个人笔记公司项目】vue项目配置代理解决跨域问题

前后端分离模式势必会遇到跨域问题&#xff0c;比如我是10.106.46.169:8080要去请求10.114.46.108:9191。下面讲下代理详细步骤。 本文步骤基于本人的项目结构 一般项目结构已支持代理 // 部署时需要将改开关置为false window.isDev trueif (window.isDev) { // Devwindow.l…

计算机网络速成(二)

计算机网络面试&#xff08;二&#xff09;-CSDN博客 OSI七层体系架构 OSI七层模型是什么&#xff1f;每层的功能是什么&#xff1f; OSI七层模型是国际标准化组织&#xff08;ISO&#xff09;制定的一个用于计算机或通信系统间互联的标准体系&#xff0c;它从上到下分别是&am…

揭秘“商业园区综合管理平台”的无代码开发流程!

本文中的素材来自我在某国资投资集团朋友小赵的“有偿”投稿&#xff0c;要知道现在的商业园区也正在经历数字化改造&#xff0c;面对多商场、多店铺的复杂管理需求&#xff0c;各类商管集团纷纷进行线上互联网管理模式的转型。 这份素材有何不同之处呢&#xff1f;因为他们走了…

EthernetIP IO从站设备数据 转IEC61850项目案例

目录 1 案例说明 1 2 VFBOX网关工作原理 1 3 准备工作 2 4 网关采集ETHERNETIP IO数据 2 5 用IEC61850协议转发数据 4 6 网关使用多个逻辑设备和逻辑节点的方法 6 7 从设备的的EDS文件获取参数信息 8 8 案例总结 10 1 案例说明 设置网关采集EthernetIP IO设备数据把采集的数据…

成功解决:el-popconfirm组件来确认删除、修改等操作无效

我 | 在这里 ⭐ 全栈开发攻城狮、全网10W粉丝、2022博客之星后端领域Top1、专家博主。 &#x1f393;擅长 指导毕设 | 论文指导 | 系统开发 | 毕业答辩 | 系统讲解等。已指导60位同学顺利毕业 ✈️个人公众号&#xff1a;热爱技术的小郑。回复 Java全套视频教程 或 前端全套视频…

深入理解java web分层架构的高内聚低耦合

​ 在软件开发中&#xff0c;构建一个高效、可维护且可扩展的应用系统一直是开发者追求的目标。分层架构和依赖注入&#xff08;IOC&#xff09;是实现这一目标的重要策略。本文将深入探讨三层架构的高内聚特性、低耦合的设计原则&#xff0c;以及如何通过IOC&#xff08;控制反…

前端宝典之五:React源码解析之深度剖析Diff算法

本文主要针对React源码进行解析&#xff0c;内容有&#xff1a; 1、Diff算法原理、两次遍历 2、Diff瓶颈及限制 3、Diff更新之单节点和多节点原理 一、Diff源码解析 以下是关于 React Diff 算法的详细解析及实例&#xff1a; 1、React Diff 算法的基本概念和重要性 1.1 概念…

非专业人员该学什么程序语言

编程&#xff0c;一度被认为和驾驶一样是一项现代社会的基本技能&#xff0c;非专业人员也该有所掌握&#xff0c;中小学也在教。但实际上&#xff0c;它的普及程度远比驾驶差&#xff0c;掌握这个技能的人很少&#xff0c;在学校学过的知识&#xff0c;因为工作中用不上也都忘…

一文弄懂评分卡是什么

在最开始的信用审批过程中,客户的信用等级主要由专家进行主观评判。随着数据分析工具的发展和数据收集、存储越来越容易,各大机构逐渐使用统计模型将专家的评判标准量化为评分卡模型。从而更有利于客观评价客户风险,和批量高效对客户进行风险分级。随着技术的发展,机器学习…

力扣经典题目~快乐数~零基础也能看懂哦

202. 快乐数https://leetcode.cn/problems/happy-number/ 题目描述&#xff1a; 编写一个算法来判断一个数 n 是不是快乐数。 「快乐数」 定义为&#xff1a; 对于一个正整数&#xff0c;每一次将该数替换为它每个位置上的数字的平方和。然后重复这个过程直到这个数变为 1&…

MyBatisX逆向工程

目录 逆向工程 准备好数据库、表 安装MyBatisX插件 项目连接数据库 引入依赖pom.xml 生成实体类、映射文件、接口 逆向工程 正向工程&#xff1a;先创建Java实体类&#xff0c;由框架负责根据实体类生成数据库表。Hibernate是支持正向工程的。 逆向工程&#xff1a;先创…

晶体管电路设计学习(一)放大电路的工作

我们这里学习晶体管电路设计&#xff0c;会从晶体管到场效应管直到复杂的运放器件&#xff0c;主要是进行体系化的深入学习&#xff0c;只是一个学习和记录的过程。 放大电路的作用是将小信号放大为大信号。例如,将0.1V的信号提高为1V 信号----即是放大。 1.首先,用晶体管组成一…

TinyC编译器4—编译器基本流程

1.什么是编译器&#xff0c;为什么要开发编译器 编译器&#xff1a;将一种程序语言翻译为另一种程序语言的计算机程序。一般来说&#xff0c;源程序为高级语言&#xff0c;而目标语言则是汇编语言或者机器码。 一开始的程序员是用机器码写程序&#xff0c;非常容易出错&#…

UE5中制作箭头滑动转场

通过程序化的方式&#xff0c;可以制作一些特殊的转场效果&#xff0c;如箭头划过的转场&#xff1a; 1.制作思路 我们知道向量点积可以拿来做投影&#xff0c;因此可以把UV空间想象成向量坐标&#xff0c;绘制结果就是在某个向量上的投影&#xff1a; 绘制结果似乎是倾斜方…

【ISAC】Federated Edge Learning With Misaligned Over-The-Air Computation

[1]-Tse, David, and Pramod Viswanath. Fundamentals of wireless communication. Cambridge university press, 2005. 文章目录 1-综述2-系统模型 1-综述 misaligned OAC&#xff1a;预编码矩阵&#xff08;含噪声&#xff09; 没同步好 2-系统模型 θ ∈ R d \theta \in\m…

云计算实训31——playbook(剧本)基本应用、playbook常见语法、playbook和ansible操作的编排

playbook(剧本): 是ansible⽤于配置,部署,和管理被控节点的剧本。⽤ 于ansible操作的编排。 使⽤的格式为yaml格式 一、YMAL格式 以.yaml或.yml结尾 ⽂件的第⼀⾏以 "---"开始&#xff0c;表明YMAL⽂件的开始(可选的) 以#号开头为注释 列表中的所有成员都开始于…

耐氟化氢PFA蒸馏冷凝装置PFA烧瓶应用于氟化工半导体行业领域

氟化氢&#xff0c;化学式为 HF&#xff0c;是一种无色、有刺激性气味的气体&#xff0c;它在空气中会形成白色的雾。氟化氢具有很强的腐蚀性&#xff0c;能够侵蚀许多金属和非金属材料。这种腐蚀性使得氟化氢在工业上被用于蚀刻玻璃、清洗半导体器件以及加工金属等领域。 氟化…

Ubuntu | 更换 Solc 版本

目录 第一步&#xff1a;安装 pip3第二步&#xff1a;安装 solc-select第三步&#xff1a;查看可安装版本第四步&#xff1a;安装指定版本第五步&#xff1a;使用指定版本 前言&#xff1a;部署智能合约时报错&#xff0c;发现是 Solc 版本太高。 参考博客&#xff1a;Solc 安…

Spring Boot整合Quartz框架

说明&#xff1a;Quartz是一个定时器框架&#xff0c;可以实现定时任务&#xff0c;本文介绍如何在Spring Boot项目中整合Quartz框架&#xff0c;Quartz介绍参看下面这篇文章&#xff1a; 【Quartz】Quartz定时任务框架 创建Demo 首先&#xff0c;创建一个Spring Boot项目&a…

Qt Creator安装配置指南

1.官网下载在线安装包 官网地址&#xff1a; https://www.qt.io/download-dev#eval-form-modal 2.双击在线安装包按引导流程安装qt 3.选择自己要配置的qt环境版本 3.1如果要选中低版本的qt环境我这里安装的是qt5.15.2的(其他低版本也一样的)&#xff0c;要勾选上Archive(存…