C++初探 5-2(while循环 do while循环 输入 二维数组)

news2024/10/7 8:31:08

目录

while循环

for 与 while

编写延时循环

do while循环

基于范围的for循环(C++11)

循环和文本输入

使用原始的cin进行输入

使用cin.get(char)进行补救

使用不同的cin.get( )

文件尾条件

另一个cin.get( )版本

嵌套循环和二维数组

初始化二维数组

使用二维数组


本笔记参考:《C++ PRIMER PLUS(第6版)》


while循环

        可以把while循环看作没有初始化和更新部分的for循环,即while循环只存在测试条件和循环体:

        和for循环一样,① 当while循环的测试表达式值为true时,执行循环体中的语句。② 执行完毕后,返回测试表达式重新进行评估,直到测试条件为false。

使用例:遍历字符串,显示其中的字符及其ASCII码。

#include<iostream>
const int ArSize = 20;
int main()
{
	using namespace std;
	char name[ArSize];
	cout << "请输入一个单词(英文):";
	cin >> name;

	cout << "这个单词拥有的字符及其ASCII码是:\n";
	int i = 0;
	while (name[i] != 0)
	{
		cout << name[i] << ": " << int(name[i]) << endl; 
		i++;
	}

	return 0;
}

程序执行的结果是:

【分析】

        在上述程序的while循环的最后,存在 i++; 这样的语句,while循环需要通过类似于这种语句去更新测试表达式的结果,否则可能会进入死循环。

        当然,上述while行可以改成这样:

while (name[i])

        此时,测试表达式有两个可能值:

  • 若name[i]是常规字符,其值应该为 true 或者 一个非零值(对应字符的编码)
  • 若name[i]是空值字符,其值应该为 false 或者 0 。

        另外,在上述程序中,为了打印字符的ASCII码,使用了强制类型转换,否则cout将会把name[i]解释为字符编码。

    string对象并没有使用空字符标记字符串末尾,如果使用string对象,就要对应改变上述程序。

for 与 while

        在本质上,for循环和while循环是相同的。例如:

  1. 下方的for循环:
    for (int i = 0; i < 10; i++)
    {
        cout << i << endl;
    }

    可改成对应的while循环:

    int i = 0;
    while (i < 10)
    {
        cout << i << endl;
        i++;
    }
  2. 或者将while循环:
    while (j > 0)
    {
        i += j;
        j--;
    }

    改写为对应的for循环:

    for ( ; j > 0; )
    {
        i += j;
        j--;
    }

        对于for循环而言,其需要的3个表达式均可以是空表达式,只有分号是必须要有的。不过如果测试表达式为空,那么这个for循环将会是一个死循环,类似于:

int i = 0;
for (; ;)
	cout << i++ << endl;

        因此,在设计循环时,需要知道3个条件:

  1. 循环终止的条件;
  2. 首次测试前的初始化条件;
  3. 在条件被再次测试之前的更新条件。

        for循环在结构上明确指出了这3个条件。而在无法预知循环的执行次数时,程序员会使用while循环。

    在书写循环时,可能会出现这种情况:

i = 0;
while (name[i] != '\0');        //存在问题:多写了一个分号
{
    cout << name[i] << endl;
    i++;
}

    上述代码在while行中多插入了一个分号,因为分号结束语句,因此分号将会结束while循环(即上述循环的循环体为空语句)。所以,上述循环不执行任何操作,成为了一个死循环。

编写延时循环

        在一种用于个人计算机的早期技术中,会通过while循环的使用来进行延时操作:

int main()
{
	long wait = 0;
	while (wait < 1000000)
		wait++;

	return 0;
}

但这种延时方式受到计算机处理器的限制,在不同的计算机上可能需要不同的计数限制。另外,现在计算机的计算速度已经很快了,通过这种方式进行延时操作并不合适。

        而现在,ANSI C和C++库提供了一个函数,clock( ) ,它能够返回出现开始执行后所用的系统时间。但依旧存在一些问题:

  1. clock( )返回的时间,单位不一定是 秒 ;
  2. clock( )的返回类型并不一致,可能是long,也可能是unsigned long等等。

        为此,需要使用头文件<ctime>(time.h)提供的一个符号常量:CLOCKS_PER_SEC,该常量等于每秒钟包含的 系统时间单位数 。由此就得到了两个计算公式:

        另一方面,<ctime>clock_t 作为clock( )返回值的别名(类型别名),即只要把变量声明为 clock_t 类型,编译器就将自带匹配与clock( )返回值相符的类型。

例子:

#include<iostream>
#include<ctime>
int main()
{
	using namespace std;
	cout << "请输入需要延迟的时间(单位是秒):";
	float secs;
	cin >> secs;
	clock_t delay = secs * CLOCKS_PER_SEC;

	cout << "开始计时\a\n";
	clock_t start = clock();
	while (clock() - start < delay);

	cout << "完成\a\n";

	return 0;
}

程序执行的结果:

        上述程序选择了以系统时间为单位(不以秒为单位)进行延迟时间的计算,省去了在每轮循环中将系统时间转换成秒的操作。

        在之前提到过,clock_t 是一个系统别名,而C++创建别名的方式有两种:

  1. 使用预处理器,例如:
    #define BYTE char

    预处理器将使用char类型替换程序中出现的所有BYTE,这就使BYTE成为了char的别名;

  2. 使用关键字typedef创建别名,例如:

    typedef char byte;    //将 byte 作为char的别名

    通用格式:

    如果要让 byte_pointer 成为char指针的别名,可以这样做:

    typedef char* byte_pointer;

    尽管上述两种方法都可以用来创建别名,但是在使用 #define 声明一系列变量时应该注意:

#define FLOAT_POINTER float*
FLOAT_POINTER pa, pb;

    上述代码在预处理器的转换后,会变成这样:

float* pa, pb;    //此时,pa是一个浮点型指针,pb是一个浮点型变量

    不过typedef不会有这样的问题,它能够处理更复杂的类型别名。但注意,typedef不会创建新的类型,它只是为已有的类型创建一个新的名称。

do while循环

        do while循环不同于之前的两种循环,它是出口条件循环:先执行循环体,再进入测试表达式。因此,do while循环至少会执行一次。其句式为:

        do while循环的程序流程:

        因为出口条件循环本身的结构, 有时候适合入口条件循环的场合并不一定适合do while循环,但在一些情况下,do while循环要更为合理。例如:请求用户输入,程序要先获得输入,再进行测试。

使用例:

#include<iostream>
int main()
{
	using namespace std;
	int n;

	cout << "请输入一个数字(范围是1-10)\n";
	do
	{
		cin >> n;		//先执行语句
	} while (n != 7);	//再进行测试
	cout << "与系统数字匹配成功。\n";

	return 0;
}

程序执行的结果是:

    另一方面,存在如下的循环:

int I = 0;
for (;;)
{
	I++;
    //内部执行的一些操作
	if (30 >= I)
		break;
}

或者

int I = 0;
for (;; I++)
{
	if (30 >= I)
		break;
	//内部执行的一些操作
}

    上述代码可读性差,也并非编写循环的通用模型。但第一个例子使用 do while循环 会使得代码表达更加清晰:

//对应之前的第一个例子
int I = 0;
do
{
	I++;
	//进行一些操作
} while (30 > I);

    类似地,第二个例子使用 while循环 会更易理解:

int I = 0;
while (I < 30)
{
	//进行一些操作
	I++;
}

基于范围的for循环(C++11)

        C++11新增了一种循环:基于范围的for循环。这简化了对于数组(或容器类,包括vector和array)的每个元素执行相同的操作,例如:

#include<iostream>
int main()
{
	using namespace std;
	double prices[5] = { 4.99, 10.99, 6.87, 7.99, 8.49 };

	for (double x : prices)
		cout << x << endl;

	return 0;
}

程序执行的结果是:

【分析】

        先看语句:

for (double x : prices)

在这条语句中,x 最初表示数组prices的第一个元素。此后,随着循环进行,x 依次表示了数组中的每个元素。

        类似地,可以通过上述方式进行数组元素的修改:

for (double& x : prices)   //& 表示引用变量
	x = x * 0.80;

        还可以将这种语法与初始化列表结合起来:

for (int x : {3, 5, 2, 8, 6})
	cout << x << " ";
cout << "\n";

打印结果:

循环和文本输入

        通过循环,能够完成一类常见、重要的工作:逐字符地读取来自文件或键盘的文本。在C++中,因为cin对象支持三种不同模式的单字符输入,其用户接口各不相同,所以需要分开讨论。

使用原始的cin进行输入

        为了明确读取文本的循环停止的条件,有时,会选择某个特殊字符(哨兵字符),将其作为停止标记。譬如,下方的例子规定:在遇到 #字符 时停止读取输入。

例子

#include<iostream>
int main()
{
	using namespace std;

	char ch;
	int count = 0;
	cout << "请输入字符(输入 # 时,结束文本读取):\n";
	cin >> ch;            //读取第一个字符(初始化)
	cout << "\n读取到的字符是:\n";
	while (ch != '#')     //(测试)
	{
		cout << ch;       //打印读取的字符
		++count;          //进行读取字符的计数
		cin >> ch;        //读取下一个字符(更新)
	}
	cout << "\n\n读取了 " << count << " 个字符。\n";

	return 0;
}

程序执行的结果是:

【分析】

        该循环在循环开始前就读取了第一个字符,这是为了让循环能够测试第一个字符(第一个字符也可能是'#')。

        可以发现,程序在输出时忽略了空格(seeyouagain),这是因为 cin 在读取char值(或者其他基本类型)时,将自动省略空格和换行符。因此上述程序中,空格也没有被包含在计数(count)内。

        另外,发送给cin的输入会先进入缓冲区,当用户输入回车键时,再统一发送给程序。这也解释了为什么在运行程序时,可以在 # 后面输入字符(因为程序在遇到 # 时就结束了对输入的处理)


使用cin.get(char)进行补救

        之前提到,通过原始的cin进行输入会忽略空格和换行符。而在cin所属的istream类中,包含了一个能够读入每个字符(包括空格、制表符和换行符)的成员函数cin.get( )

例子:

#include<iostream>
int main()
{
	using namespace std;

	char ch;
	int count = 0;
	cout << "请输入字符(输入 # 时,结束文本读取):\n";
	//cin >> ch;
	cin.get(ch);
	cout << "\n读取到的字符是:\n";
	while (ch != '#')
	{
		cout << ch;
		++count;
		cin.get(ch);
	}
	cout << "\n\n读取了 " << count << " 个字符。\n";

	return 0;
}

程序执行的结果是:

【分析】

        这次程序打印了每个字符,并对它们进行了计数,包括空格。cin.get( )同样存在一个缓冲区,这意味着输入的字符个数可能并最终打印的要多。

解释 cin.get(ch); 

        如果用C语言的理解进行解释:该语句将 字符变量ch 传递给了 函数cin.get( )。这很明显是无效的,因为该函数的目的是修改变量ch的值,这需要的应该是ch的地址(即&ch)。

        但程序执行的结果已经告诉我们,上述代码是正确的。这是为什么?

        这是因为成员函数cin.get(ch)的参数声明是一个引用类型(引用类型是C++新增的一种类型):

使用不同的cin.get( )

        回顾曾经提到过的例子:

#include<iostream>
#define ArSize 20
int main()
{
	using namespace std;
	char name[ArSize];

	cout << "请输入名字:";
	cin.get(name, ArSize).get();

	cout << "输出:" << name << "\n";

	return 0;
}

程序执行的结果是:

        其中,存在着这条语句:

cin.get(name, ArSize).get();

这条语句可以被看作是两个连续的函数调用:

cin.get(name, ArSize);
cin.get();

        这里出现了cin.get( )的两个版本

  • 一个版本接受两个参数:① 数组名(char*类型的)字符串的地址),② ArSize(int类型的整数)
  • 另一个版本是不接受任何参数的cin.get( )。

        而在之前的例子中,还存在一个 cin.get( ) :    

  • char ch;
    cin.get(ch);

    该版本下的 cin.get( ) 接受一个char类型的参数。

        这很明显区别于C语言的函数定义,而C++之所以可以这样做,是因为该语言支持被称为函数重载的OOP特性。函数重载允许创建多个同名函数,条件是它们的参数列表不同,例如:

如果输入的参数不同,编译器将会从上述各种版本的cin.get( )中选出适合当前参数的。

        暂时总结:函数重载允许对多个相关的函数使用相同的名称,这些函数以不同的方式或针对不同的类型执行相同的基本任务。

    为区分不同的函数版本,在引用这类函数时提供参数列表。

文件尾条件

        在之前进行字符串输入的例子中,为了检测字符串输入完毕,需要在字符串末尾添加'#',但这明显没有考虑'#'可能是合法输入的组成部分,其他符号亦然。

        如果输入来自文件,替代上述提到的特殊字符,可以使用一种技术 —— 检测文件尾(EOF - End of File)。这需要C++输入工具和操作系统协同工作。

        首先了解两个概念:

  1. 重定向操作符( < ):很多操作系统支持重定向,即允许文件替换键盘输入,例如:
    excute < word

    其中 excute.exe 是可执行文件,word 是文本文件。通过这种方式,程序将从word文件(而不是键盘)获取输入。

  2. 允许通过键盘输入模拟文件尾条件:

    1. Unix中,需要在行首按下 Ctrl + D 来实现;

    2. Windows命令提示符中,可在任意为止按下 Ctrl + Z + Enter 实现。

    键盘输入的EOF概念是命令行环境遗留下来的。总之,很多PC环境都将 Ctrl + Z 视为模拟的EOF(不过有些系统不支持这种模拟的EOF,或者支持并不完善)。

例子:

#include<iostream>
int main()
{
	using namespace std;
	char ch;
	int count = 0;
	cin.get(ch);				//尝试进行第一个字符的读取
	while (cin.fail() == false)	//进行检测
	{
		cout << ch;
		++count;
		cin.get(ch);
	}
	cout << "\n读取了 " << count << " 个字符。\n";

	return 0;
}

程序执行的结果是:

     在检测到EOF之后,cin将会把成员常量 eofbit 和 failbit 都设置为1。此时可以通过成员函数eof( )或者fail( )进行检测,如果检测到EOF,函数会返回 true ,否则返回 false 。

(ps:fail( )和eof( )读取的都是最近的结果,它们是事后报告。)

        通过重定向,可以用该程序显示文本文件及其包含的字符数,下面是Ubantu系统上的运行结果(其中test是可执行文件,word是文本文件):

1. EOF结束输入

        正如之前提到的,cin在检测到EOF时,会在cin对象中设置一个指示EOF条件的标记。设置完毕后,cin将不再读取。但这仅针对文件输入。对于键盘输入,是有可能因为cin.clear( )清除了EOF标记,导致输入继续进行。

    目前可知的:在一些系统里,Ctrl + Z 将结束输入和输出,但cin.clear( )将无法回复输入和输出。


2. 常见的字符输入做法

        在程序的循环测试条件部分出现了这样的语句:

while (cin.fail() == false)

        之前提到过的,成员函数fail( )是有返回值的,通过将这种返回值和运算符结合起来,可以得到一种更简便的测试表达式(!运算符可以转换true和false):

while (!cin.fail())

------

        或者,因为istream类提供了一个可以将istream对象(如cin)转换为bool值的函数:当cin出现在需要bool值的位置时,该函数将被调用(在读取到EOF时,因为读取失败,将会得到的bool值是false)

while (cin)    //当成功读取输入时,执行循环。

    因为通过这种方式执行的while循环可以检测更多的失败原因,如磁盘故障,所以这种写法会更加通用。

------

        在之前的程序中,出现的输入语句是cin.get( ),该函数的返回值就是cin。因此,可以这样简化程序:

while (cin.get(ch))
{
    //内部语句
}

        这种方式使得程序在这个运行过程中只对函数cin.get(char)进行了一次调用,并且,这条语句同时凑齐了循环的三个条件,即初始化、确定结束(检测)条件和更新条件。

另一个cin.get( )版本

        还存在一种类似于 C语言的getchar( ) 的cin.get( )版本。在不接受任何参数时,cin.get( )将会返回输入中的下一个字符,例如:

ch = cin.get();

        这种版本的cin.get( )的工作方式是将字符编码作为int值返回(与其他版本存在区别:cin.get(ch)返回的是一个对象,而不是读取的字符)。类似地,存在cout.put( )函数,该函数可以进行字符的显示,工作方式类似于C语言的putchar( ):

cout.put(ch);

    最初,C++标准要求put( )成员只有一个原型,即put(char),该函数可以接受int参数。但有些C++实现提供了3个原型:put(char)、put(signed char)和put(unsigned char),此时给put( )传递一个int类型参数将导致错误,为此需要使用显式强制类型转换。

        尽管提到了多种的cin版本,但此时还有一个问题没有得到解决,那就是如何判定EOF(EOF不表示输入中的字符,而是表示没有字符)

        为此,头文件iostream中定义了一个用符号常量EOF表示的特殊值,这个值必须不同于任何有效的字符值。通常,EOF被定义为 -1

        之前提到的例子的核心:

char ch;
cin.get(ch);
while (cin.fail() == false)
{
    cout << ch;
    ++count;
    cin.get(ch);
}

可以被替换成下方的代码:

int ch;                  //ch变为 int类型 的变量
ch = cin.get();          //使用了另一个版本的cin.get()
while (ch != EOF)        //EOF测试替代了原本的cin.fail()检测
{
	cout.put(ch);        //在一些实现中可用 cout.put(char(ch)) 替代
	++count;
	ch = cin.get();
}

        需要注意,EOF表示的不是有效的字符编码,在某些系统中可能与char类型不兼容。此时需要使用int类型的变量接收cin.get( )(无参版本)的返回值,并在输出时进行强制类型转换。

使用cin.get( )方法的例子:

#include<iostream>
int main()
{
	using namespace std;
	int ch;
	int count = 0;

	while ((ch = cin.get()) != EOF)
	{
		cout.put(char(ch));
		++count;
	}
	cout << "\n读取了 " << count << " 个字符。\n";

	return 0;
}

程序执行的结果是:

【分析】

        先观察循环条件:

while ((ch = cin.get()) != EOF)

子表达式 ch = cin.get( ) 两端的括号改变了程序的运算顺序,因此,该表达式的执行顺序应为:

  1. 调用函数cin.get( );
  2. 对 ch 进行赋值;
  3. 因为赋值表达式的值为左操作数的值,因此整个子表达式的值为 ch 的值;
  4. 将子表达式(ch)的值与EOF进行比较。

        如果上述表达式中省略了子表达式的括号:

while (ch = cin.get() != EOF)

因为 !=运算符 的优先级高于 =运算符 ,所以程序将会优先执行 cin.get() != EOF ,并将得到的bool值赋给 ch ,这就偏离了程序本意。

        而如果使用 cin.get(ch) 进行输入操作就不会存在上述问题。因为当 cin.get(char) 到达EOF时,该函数不会将任何值赋给ch(即ch不会被用于存储非char值)

属性cin.get(ch)ch = cin.get( )
传递 输入字符 的方式赋给参数ch将 函数返回值 赋给ch

函数的返回值

(用于字符输入)

istream对象

(执行向bool值的转换后,得到 true

int类型的字符编码

函数的返回值

(到达EOF时)

istream对象

(执行向bool值的转换后,得到 false

EOF

        如果使用的是带有字符参数的版本,那么在进行字符拼接时将会更方便:

cin.get(ch_1).get(ch_2);

这条语句将输入中的下一个字符赋给 ch_1 ,并将接着的下一个字符赋给 ch_2 。之所以可以这样处理,是因为 cin.get(ch_1) 返回的是一个cin对象,可以使用整个对象再次进行get( )的调用。

嵌套循环和二维数组

        如果把一维数组看作一行数据,那么二维数组就是一个表格(既有数据行,也有数据列)

        尽管C++没有提供二维数组类型,但用户可以创建这样一个数组,让数组的元素本身就是数组。例如:

int maxtemps[4][5];

上述声明说明:

  • maxtemps是一个包含了 4个元素 的数组;
  • 每个元素都是包含了 5个int类型元素 的数组。

        其中:

  • maxtemps[0]即是maxtemps数组的第一个元素,本身也是由5个int类型元素组成的元素;
  • maxtemps[0][0]是maxtemps[0]数组的第一个元素,本身是int类型。

        因此,可以将二维数组看作一个表格,第一个下标表示行,第二个下标表示列:

打印二维数组maxtemps的所有内容:

for (int row = 0; row < 4; row++)
{
	for (int col = 0; col < 5; ++col)
		cout << maxtemps[row][col] << "\t";
	cout << endl;
}

初始化二维数组

        参照一维数组的初始化方式(提供一个值列表),二维数组的初始化可以看作是一系列的一维数组的初始化:

int maxtemps[4][5] =
{
	{1, 2, 3, 4, 5},		//初始化数组maxtemps[0]
	{6, 7, 8, 9, 10},		//初始化数组maxtemps[1]
	{11, 12, 13, 14, 15},	//初始化数组maxtemps[2]
	{16, 17, 18, 19, 20}	//初始化数组maxtemps[3]
};

使用二维数组

例子:

#include<iostream>
const int Cities = 5;
const int Years = 4;

int main()
{
	using namespace std;
	const char* cities[Cities] =
	{
		"厦门",
		"浙江",
		"昆明",
		"上海",
		"吉林"
	};
	int maxtemps[Years][Cities] =	//数据是编的
	{
		{36, 37, 35, 30, 25},
		{37, 38, 36, 31, 24},
		{38, 36, 36, 31, 26},
		{40, 39, 38, 33, 27},
	};

	cout << "2008 - 2011的最高气温(编的)\n\n";
	for (int city = 0; city < Cities; city++)
	{
		cout << cities[city] << ":\t";
		for (int year = 0; year < Years; year++)
			cout << maxtemps[year][city] << "\t";
		cout << endl;
	}

	return 0;
}

程序执行的结果是:

【分析】

        不同于之前的程序,该程序将列循环(城市索引)放在了外面,而将行循环(年份索引)放在了里面。

        另一方面,该程序提供声明一个char指针数组来存储城市的名字。但是,使用char类型的二维数组也是可行的:

const char cities[Cities][25] =
{
	"厦门",
	"浙江",
	"昆明",
	"上海",
	"吉林"
};

这种写法规定了5个字符串的最大长度为24个字符,而数组本身存储的是这5个字符串的首字符的地址。

    从这里可以看出,二维数组在进行元素修改时拥有更大优势(因为二维数组可以通过索引快速找到元素),而指针数组因为不用开辟多余的空间,所以更加经济。

        除此之外,还可以使用string对象对城市名称进行存储:

const string cities[Cities] =
{
	"厦门",
	"浙江",
	"昆明",
	"上海",
	"吉林"
};

因为string类拥有自动调整大小的特性,因此在这种地方要比二维数组来得方便。

    因为使用了const限定符,使用这里的字符串实际上是无法进行修改的。

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

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

相关文章

长视频又添新变数

配图来自Canva可画 互联网广告市场依旧没有等来春天。据QuestMobile数据显示&#xff0c;2021下半年&#xff0c;中国互联网广告市场规模为3578.2亿元&#xff0c;而在2022年上半年这一数值下降至2903.6亿元&#xff0c;且同比增长率为-2.3%。 反应到具体的互联网平台上&…

[附源码]java毕业设计流浪动物救助网站

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

Zookeeper系列——概述

Zookeeper系列——概述Zookeeper官方文档模型结构模型的特点节点的类型持久节点(PERSISTENT)持久顺序节点(PERSISTENT_SEQUENTIAL)临时节点(EPHEMERAL)临时顺序节点(EPHEMERAL_SEQUENTIAL)安装Zookeeper启动进入容器连接zookeeper的cli配置文件&#xff08;zoo_sample.cfg&…

基于微信小程序的足浴城消费系统设计与实现-计算机毕业设计源码+LW文档

小程序开发说明 开发语言&#xff1a;Java 框架&#xff1a;ssm JDK版本&#xff1a;JDK1.8 服务器&#xff1a;tomcat7 数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09; 数据库工具&#xff1a;Navicat11 开发软件&#xff1a;eclipse/myeclipse/idea Mav…

m基于simulink的WCDMA通信链路仿真

目录 1.算法概述 2.仿真效果预览 3.核心MATLAB代码预览 4.完整MATLAB程序 1.算法概述 W-CDMA由ETSI NTT DoCoMo作为无线介面为他们的3G网路FOMA开发。后来NTTDocomo提交给ITU一个详细规范作为一个象IMT-2000一样作为一个候选的国际3G标准。国际电信联盟(ITU) 最终接受W-CDM…

ESP32-WROOM-32 ESP32 wifi模块基本参数与引脚定义

基本参数&#xff1a; WiFi描述标准FCC/CE/TELEC/KCC/SRRC/NCC协议 802.11 b/g/n/e/i (802.11n&#xff0c;速度高达150Mbps) A-MPDU和A-MSDU聚合&#xff0c;支持0.4μS防护间隔 频率范围2.4GHz~2.5GHz(2400M~2483.5M)蓝牙描述协议符合蓝牙v4.2BR/EDR和BLE标准射频 具有-98dB…

nosql课后答案

文章目录第一章 绪论1. NoSQL和关系型数据库在设计目标上有何主要区别&#xff1f;2. 简要总结一下NoSQL数据库的技术特点。第二章 NoSQL数据库的基本原理1. 描述分布式数据管理的特点。2 什么是CAP原理&#xff1f;CAP原理是否适用于单机环境&#xff1f;3. 简述BASE理论的具体…

杨紫开直播被吐槽脸胖、脖子粗、嘴唇厚,这就是明星开美颜的原因

自从发明了美颜&#xff0c;人人都变成了美女&#xff0c;不过这样的话也有弊端&#xff0c;那就是真真假假虚虚实实难以辨别。爱美之心人皆有之。尤其是娱乐圈的明星&#xff0c;在直播的时候更是开启十级美颜&#xff0c;以至于整个人都变形了。 当然也有不开美颜的明星&…

【技术分享】计算机视觉常见的十种图像标注方法

文章目录1.语义分割2.矩形框标注3.多边形标注4.关键点标注5.立方体标注6.3D点云标注7.2D/3D融合标注8.目标追踪9.OCR转写10.属性识别1.语义分割 语义分割是指根据物体的属性&#xff0c;对复杂不规则图片进行进行区域划分&#xff0c;并标注对应上属性&#xff0c;以帮助训练图…

工业互联网MES解决方案-最新全套文件

工业互联网MES解决方案-最新全套文件一、建设背景生产企业面临的问题&#xff1a;二、思路架构MES系统的实现对企业的影响&#xff1a;三、建设方案四、获取 - 工业互联网MES全套最新解决方案合集一、建设背景 MES&#xff08;生产制造执行系统&#xff09;在整个企业生产过程…

《FFmpeg Basics》中文版-08-模糊,锐化和其他去噪

正文 包含各种噪声的视频输入可以使用去噪滤波器和选项来增强。 在视频编码之前&#xff0c;去噪是视频预处理的一部分。 模糊视频效果 模糊效果用于提高图像&#xff08;视频帧&#xff09;中某些类型的噪声的质量&#xff0c;其中每个输出像素值是根据相邻像素值计算的。 …

java项目-第138期ssm就业信息管理系统-java毕业设计_计算机毕业设计

java项目-第138期ssm就业信息管理系统-java毕业设计_计算机毕业设计 【源码请到资源专栏下载】 今天分享的项目是《ssm就业信息管理系统》 该项目分为管理员和普通用员2个角色。 普通用户有就业信息、就业统计2个功能 管理员用户有就业信息、 就业统计&#xff1a;按专业统计 …

AVR单片机及其编译软件

内容包括AVRStudio及WinAVR介绍&#xff0c;软件下载地址&#xff0c;编译环境设置&#xff0c;IAR for AVR的使用&#xff0c;AVR单片机的介绍。紫色文字是超链接&#xff0c;点击自动跳转至相关博文。持续更新&#xff0c;原创不易&#xff01; 目录&#xff1a; 一、AVRSt…

用Python脚本能获取Wifi密码么?能。

注意&#xff0c;本文不是破解 WIFI 密码&#xff0c;当然你把程序发给别人再获取对方密码&#xff0c;那是社会工程学。 文章目录⛳️ 实战场景与 subprocess 模块介绍⛳️ Python 获取本地 Wifi 密码⛳️ 实战场景与 subprocess 模块介绍 这篇博客给大家带来一个小小的案例&…

魏副业而战:做闲鱼比打工强

我是魏哥&#xff0c;与其在家躺平&#xff0c;不如魏副业而战&#xff01; 学员小D做闲鱼又赚了122元&#xff0c;并在社群中晒了收入截图&#xff0c;大家纷纷点赞。 小D说&#xff0c;做闲鱼比打工强&#xff0c;一边聊天&#xff0c;一边赚钱&#xff0c;很喜欢这种赚钱方…

多线程服务器端的实现

理解线程的概念 引入线程的背景 多进程模型的缺点 ①、创建进程的过程会给操作系统带来相当沉重的复旦 ②、为了完成进程间数据交换&#xff0c;需要特殊的IPC技术 ③、每秒少则数十次、多则数千次的“上下文切换”是创建进程时最大的开销&#xff08;主要&#xff09; 线…

2022实验室更新 DBCO-NH2,DBCO-Amine 叠氮化物功能化化合物

DBCO(二苯并环辛炔) 氨基衍生物&#xff0c;可与含有羧基的生化小分子形成稳定酰胺键连接。DBCO-NHS酯是一种与胺反应的化合物&#xff0c;可用于修饰含胺分子(在水性介质中的溶解度有限)。它与伯胺(例如赖氨酸的侧链氨基或多肽的N端氨基)在中性或弱碱性pH下反应形成共价键。这…

某政府门户网站维护项目运维方案

一.1 运维总体原则 一.1.1 整体性原则 我们将综合考虑XXX目前所有门户网站相关应用系统的现状&#xff0c;提出整体的运行维护策略&#xff0c;有效保障系统运行中各环节的不间断运行&#xff0c;并综合使用不同层次的技术手段&#xff0c;为应用系统和系统依托的基础环境提供全…

【AI理论学习】多模态介绍及当前研究方向

多模态介绍及当前研究方向什么是多模态&#xff1f;多模态的任务和数据集有哪些&#xff1f;多种模态融合的方式有哪些&#xff1f;多模态任务的研究方向有哪些&#xff1f;参考资料什么是多模态&#xff1f; 什么是多模态&#xff1f;多模态指的是多种模态的信息&#xff0c;…

Golang入门笔记(8)—— init 函数

init 函数 &#xff1a; 每一个源文件都可以包含一个init函数&#xff0c;该函数会在 程序入口main函数执行前 &#xff0c;被Go运行的框架进行调用。 测试代码&#xff1a; package mainimport ("fmt" )func init() {fmt.Println("init...") }func main(…