版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
北京邮电大学
基于Matlab的MIMO通信系统仿真
专业:信息工程
班级:2011211126
姓名:
学号:
目录
TOC\o"1-3"\h\u
28961
一、概述
1
6265
1、课题的研究背景
1
3741
2、课程设计的研究目的
1
8089
3、MIMO系统
1
10909
【1】MIMO的三种主要技术
1
18202
【2】MIMO系统的概述
2
4788
【3】MIMO系统的信道模型
2
32678
二、基本原理
3
28864
1、基本流程
3
16404
2、MIMO原理
3
19174
3、空时块码
4
24050
三、仿真设计
5
28787
1、流程图
5
25459
2、主要模块及参数
6
8859
3、信源产生
6
5528
4、信道编码
6
119
5、调制
7
13514
6、AWGN信道
7
14255
7、输出统计
8
4943
四、程序块设计
8
18355
1、代码
8
14384
五、仿真结果分析
12
21356
1、仿真图
12
14993
2、结果分析
12
7628
六、重点研究的问题
12
8329
七、心得与体会
13
28597
八、参考文献
13
一、概述
1、背景
MIMO表示多输入多输出。在第四代移动通信技术标准中被广泛采用,例如IEEE802.16e(Wimax),长期演进(
LTE
)。在新一代
无线局域网
(
WLAN
)标准中,通常用于IEEE
802.11
n,但也可以用于其他802.11技术。MIMO有时被称作空间分集,因为它使用多空间通道传送和接收数据。只有站点(移动设备)或接入点(AP)支持MIMO时才能部署MIMO。
MIMO技术可以显著克服信道的衰落,降低误码率。该技术的应用,使空间成为一种可以用于提高性能的资源,并能够增加无线系统的覆盖范围。
通常,多径要引起衰落,因而被视为有害因素。然而研究结果表明,对于MIMO系统来说,多径可以作为一个有利因素加以利用。MIMO系统在发射端和接收端均采用多天线(或阵列天线)和多通道,MIMO的多入多出是针对多径无线信道来说的。传输信息流s(k)经过空时编码形成N个信息子流ci(k),I=1,……,N。这N个子流由N个天线发射出去,经空间信道后由M个接收天线接收。多天线接收机利用先进的空时编码处理能够分开并解码这些数据子流,从而实现最佳的处理。
2、课程设计的研究目的
设计一个基于Matlab的MIMO通信系统仿真。
3、MIMO系统
【1】MIMO的三种主要技术
当前,MIMO技术主要通过3种方式来提升无线传输速率及品质:
(1)空间复用(SpatialMultiplexing):
系统将数据分割成多份,分别在发射端的多根天线上发射出去,接收端接收到多个数据的混合信号后,利用不同空间信道间独立的衰落特性,区分出这些并行的数据流。从而达到在相同的频率资源内获取更高数据速率的目的。
(2)传输分集技术,以空时编码(SpaceTimeCoding)为代表:
在发射端对数据流进行联合编码以减小由于信道衰落和噪声所导致的符号错误率。空时编码通过在发射端增加信号的冗余度,使信号在接收端获得分集增益。
(3)波束成型(BeamForming):
系统通过多根天线产生一个具有指向性的波束,将信号能量集中在欲传输的方向,从而提升信号质量,并减少对其他用户的干扰。
【2】MIMO系统的概述
多输入多输出(Multi-inputMulti-output;MIMO)是一种用来描述多
\o"天线"
天线
\o"无线通信"
无线通信
\o"系统"
系统
的抽象数学模型,能利用发射端的多个天线各自独立发送信号,同时在接收端用多个天线接收并恢复原信息。该技术最早是由
\o"马可尼"
马可尼
于1908年提出的,他利用多天线来抑制
\o"信道衰落"
信道衰落
(fading)。根据收发两端天线数量,相对于普通的单输入单输出系统(Single-InputSingle-Output,SISO),MIMO此类多天线技术尚包含早期所谓的“
\o"智能型天线"
智能型天线
”,亦即单输入多输出系统(Single-InputMulti-Output,SIMO)和多输入单输出系统(Multiple-InputSingle-Output,MISO)。
由于MIMO可以在不需要增加带宽或总发送功率耗损(transmitpowerexpenditure)的情况下大幅地增加系统的数据
\o"吞吐量"
吞吐量
(throughput)及发送距离,使得此技术于近几年受到许多瞩目。MIMO的核心概念为利用多根发射天线与多根接收天线所提供之空间自由度来有效提升无线通信系统之
\o"频谱效率"
频谱效率
,以提升传输速率并改善通信质量。
【3】MIMO系统的信道模型
采用多发送多接收的天线系统,副发送天线,副接收天线的MIMO的系统信道模型如图1.3所示。用表示第i根发送天线到第j根接收天线之间的信道衰落系数,表示i副发送天线发送的信号,为第j副接收天线接收到的信号,考虑平坦的衰落信道则它们之间关系写成矩阵的形式为:,
其中定义表示n发射天线在发射的信号向量;表示n接收天线在时间t接收的信号向量;
表示t时刻的加性高斯白噪声向量;
,H为信道衰落系数矩阵。其中的幅度服从Rayleigh分布。
二、基本原理
1、基本流程
2、MIMO原理
核心思想:时间上空时信号处理同空间上分集结合。
时间上空时通过在发送端采用空时码实现:
空时分组、空时格码,分层空时码。
空间上分集通过增加空间上天线分布实现。此举可以把原来对用户来说是有害的无线电波多径传播转变为对用户有利。
MIMO系统模型:
MIMO信道模型
分集与复用
根据各根天线上发送信息的差别,MIMO可以分为发射分集技术和空间复用技术。
发射分集:在不同的天线上发射包含同样信息的信号(信号的具体形式不一定完全相同),达到空间分集的效果,起到抗衰落的作用
典型代表:空时块码(STBC)
空间复用:在不同的天线上发射不同的信息,获得空间复用增益,从而大大提高系统的容量和频谱利用率
典型代表:分层空时码
空时块码
Alamouti提出了采用两个发射天线和一个接收天线的系统可以得到采用一个发射天线两个接收天线系统同样的分集增益。
将每k个输入字符映射为一个矩阵,矩阵的每行对应在p个不同的时间间隔里不同天线上所发送的符号。
2*2举例:
三、仿真设计
1、流程图
2、主要模块及参数
3、信源产生
产生独立等概二进制信源
Matlab函数:randsrc()
编码块长度:
40-6114(3GPPTS36.212Table5.1.3-3)
推荐值:320,1024,2560,5120
利用randsrc()随机产生0与1的数,利用公式将其变成1与-1,即产生信源。
4、信道编码
Option1:卷积码(3GPPTS25.212)
根据要求,卷积码编码器为(3,1,8)编码器,G0=(001101111)转换为八进制为557;G1=(010110011)转换为八进制为663;G1=(011001001)转换为八进制为711.卷积码记忆长度为9.
5、调制
调制模块基本要求:QPSK
QPSK调制的函数可以利用matlab函数库自带的QPSK函数进行编写。但是由于QPSK是M=4进行映射的,所以将随机产生的信源利用reshape函数变成两列,即00映射成,01映射成,10映射成,11映射成。解调时利用matlab自带的demodulate函数。
6、AWGN信道
Matlab实现:randn()
信噪比与AWGN噪声的关系:
由于信源经过QPSK调制,相当于在两条坐标轴的平面(一条实数轴,一条虚数轴)每一个方向都有随机的高斯白噪声分布,然后各自乘以相应的幅度,将得出的噪声加入QPSK调制的信号里,得到的便是经过AWGN信道的信号。
7、输出统计
误码率统计
输出:
横坐标-SNREb/N0(Eb/N0vsEs/N0?)
纵坐标-BER(误比特率),BLER(误块率)
画图:semilogy(x,y)
程序块设计
代码
[1]、MIMO:
SNR_dB=0:1:30;%信噪比范围
LOOP=500;
%
%信源产生
%
fori=1:length(SNR_dB)
snr=10^(SNR_dB(i)/10);%信噪比转换
sgma=sqrt(8/snr/3);%噪声方差
error0=0;
error1=0;
error2=0;
error3=0;
fora=1:LOOP
N=2560;%仿真序列长度
S=randsrc(1,N,[0,1]);%二进制序列信源产生n个随机数
%
%有信道编码
%
S00=convolutionalcode(S);
%QPSK调制
s=QPSK(S00);
s0=zeros(1,3*N/4);%将调制后的信息奇偶拆分成两个信息以进行MIMO发射
s1=zeros(1,3*N/4);
forb1=1:2:(3*N/2)
s0(ceil(b1/2))=s(b1);
s1(ceil(b1/2))=s(b1+1);
end
N1=size(s0,2);
%有信道编码(2发2收)
h0=sqrt(0.5).*(randn(1,N1)+1i.*randn(1,N1));%设置信道冲激响应
h1=sqrt(0.5).*(randn(1,N1)+1i.*randn(1,N1));
h2=sqrt(0.5).*(randn(1,N1)+1i.*randn(1,N1));
h3=sqrt(0.5).*(randn(1,N1)+1i.*randn(1,N1));
%接收到的信号(冲激响应与发送序列卷积)
R0=h0.*s0+h1.*s1;%接收信号矢量(不含高斯噪声)
R1=-conj(s1).*h0+h1.*conj(s0);%移动通信P166
R2=h2.*s0+h3.*s1;
R3=-conj(s1).*h2+h3.*conj(s0);
%通过AWGN信道加入噪声后的冲击序列
r0=(R0+sgma.*(randn(1,N1)+1i*randn(1,N1)));%接收信号矢量(有噪声)
r1=(R1+sgma.*(randn(1,N1)+1i*randn(1,N1)));
r2=(R2+sgma.*(randn(1,N1)+1i*randn(1,N1)));
r3=(R3+sgma.*(randn(1,N1)+1i*randn(1,N1)));
s_0=conj(h0).*r0+h1.*conj(r1)+conj(h2).*r2+h3.*conj(r3);%STBC空时译码
s_1=conj(h1).*r0-h0.*conj(r1)+conj(h3).*r2-h2.*conj(r3);
forl0=1:3*N/4%将接收到的信号合并
Y0(2*l0-1)=s_0(l0);
Y0(2*l0)=s_1(l0);
end
y0=DEQPSK(Y0);%QPSK解调
m0=viterbi(y0);%维特比译码
[n0,e0]=biterr(m0,S);%计算误比特率
error0=error0+n0;
%有信道编码2发1收
hr0=sqrt(0.5).*(randn(1,N1)+1i.*randn(1,N1));%瑞利信道函数
hr1=sqrt(0.5).*(randn(1,N1)+1i.*randn(1,N1));
Rr0=hr0.*s0+hr1.*s1;%接收信号矢量(不含高斯噪声)
Rr1=-conj(s1).*hr0+hr1.*conj(s0);
rN0=(Rr0+sgma.*(randn(1,N1)+1i*randn(1,N1)));%接收信号矢量(含复高斯噪声)
rN1=(Rr1+sgma.*(randn(1,N1)+1i*randn(1,N1)));
sr_0=conj(hr0).*rN0+hr1.*conj(rN1);%STBC空时译码
sr_1=conj(hr1).*rN0-hr0.*conj(rN1);
forl1=1:3*N/4%将接收到的信号合并
Y1(2*l1-1)=sr_0(l1);
Y1(2*l1)=sr_1(l1);
end
y1=DEQPSK(Y1);%QPSK解调
m1=viterbi(y1);%维特比译码
[n1,e1]=biterr(m1,S);%计算误比特率
error1=error1+n1;
%
%无信道编码
%
sn=QPSK(S);%QPSK调制
forb2=1:2:(N/2)%将调制后的信息奇偶拆分成两个信息以进行MIMO发射
sn0(ceil(b2/2))=sn(b2);
sn1(ceil(b2/2))=sn(b2+1);
end
N2=size(sn0,2);
%无信道编码(2发2收)
hn0=sqrt(0.5).*(randn(1,N2)+1i.*randn(1,N2));%瑞利信道函数
hn1=sqrt(0.5).*(randn(1,N2)+1i.*randn(1,N2));
hn2=sqrt(0.5).*(randn(1,N2)+1i.*randn(1,N2));
hn3=sqrt(0.5).*(randn(1,N2)+1i.*randn(1,N2));
Rn0=hn0.*sn0+hn1.*sn1;%接收信号矢量(无噪声)
Rn1=-conj(sn1).*hn0+hn1.*conj(sn0);
Rn2=hn2.*sn0+hn3.*sn1;
Rn3=-conj(sn1).*hn2+hn3.*conj(sn0);
rn0=(Rn0+sgma.*(randn(1,N2)+1i*randn(1,N2)));%接收信号矢量(有噪声)
rn1=(Rn1+sgma.*(randn(1,N2)+1i*randn(1,N2)));
rn2=(Rn2+sgma.*(randn(1,N2)+1i*randn(1,N2)));
rn3=(Rn3+sgma.*(randn(1,N2)+1i*randn(1,N2)));
sn_0=conj(hn0).*rn0+hn1.*conj(rn1)+conj(hn2).*rn2+hn3.*conj(rn3);
sn_1=conj(hn1).*rn0-hn0.*conj(rn1)+conj(hn3).*rn2-hn2.*conj(rn3);
forl2=1:N/4%将接收到的信号合并
Y2(2*l2-1)=sn_0(l2);
Y2(2*l2)=sn_1(l2);
end
y2=DEQPSK(Y2);%QPSK解调
y2=y2';
[n2,e2]=biterr(y2,S);%计算误比特率
error2=error2+n2;
%无信道编码(2发1收)
hN0=sqrt(0.5).*(randn(1,N2)+1i.*randn(1,N2));%瑞利信道函数
hN1=sqrt(0.5).*(randn(1,N2)+1i.*randn(1,N2));
RN0=hN0.*sn0+hN1.*sn1;%发射序列与接收序列的卷积
RN1=-conj(sn1).*hN0+hN1.*conj(sn0);
rN0=(RN0+sgma.*(randn(1,N2)+1i*randn(1,N2)));%接收信号矢量(有噪声)
rN1=(RN1+sgma.*(randn(1,N2)+1i*randn(1,N2)));
sN_0=conj(hN0).*rN0+hN1.*conj(rN1);
sN_1=conj(hN1).*rN0-hN0.*conj(rN1);
forl3=1:N/4%将接收到的信号合并
Y3(2*l3-1)=sN_0(l3);
Y3(2*l3)=sN_1(l3);
end
y3=DEQPSK(Y3);%QPSK解调
y3=y3';
[n3,e3]=biterr(y3,S);%计算误比特率
error3=error3+n3;
end
BER0(i)=error0/(LOOP*N);
BER1(i)=error1/(LOOP*N);
BER2(i)=error2/(LOOP*N);
BER3(i)=error3/(LOOP*N);
end
semilogy(SNR_dB,BER0,'-b+');
holdon;
semilogy(SNR_dB,BER1,'r');
gridon;
semilogy(SNR_dB,BER2,'--g');
gridon;
semilogy(SNR_dB,BER3,'-.k');
gridon;
legend('2Tx2R:卷积信道编码','2Tx1R有信道编码','2Tx2R无信道编码','2Tx1R无信道编码');
xlabel('SNR/dB');
ylabel('BER');
[2]、viterbi
functiondecodingsequence=viterbi(m)
trel=poly2trellis(9,[557,663,711]);
tblen=7;%卷积码记忆深度
decodingsequence=vitdec(m,trel,tblen,'trunc','hard');
decodingsequence=decodingsequence';
[3]、QPSK
functionmodulatingsignal=QPSK(s)
s=s';
H=modem.pskmod('M',4,'InputType','Bit');
modulatingsignal=modulate(H,s);
modulatingsignal=modulatingsignal';
[4]、DEQPSK
functiondemodulatingsignal=DEQPSK(s)
h=modem.pskdemod('M',4,'OutputType','Bit');
s=s';
demodulatingsignal=demodulate(h,s);
[5]、convolutionalcode
%卷积码编码器
%msg信号
%constrainlength约束长度(寄存器数目加一)
%codegenerator冲击响应g(转换成八进制)
functioncode=convolutionalcode(msg)
constrainlength=9;
trel=poly2trellis(constrainlength,[557,663,711]);
code=convenc(msg,trel);
仿真结果分析
1、仿真图
结果分析
由误码率仿真图看出在四种信道编码的方法中:
横坐标:信噪比纵坐标:误码率
信噪比在零到五之间时四种方式的误码率都差不多。
在信噪比大于五之后2x2卷积信道编码的误码率最低、仿真性能最好。
信噪比大于8左右时2x1无信道编码的误码率最高、仿真性能最差。
2x1有信道编码和2x2无信道编码的仿真效果差不多。
有卷积码的误码率比无卷积码的低,因为卷积码有纠错功能。
六、重点研究的问题
七、心得与体会
这次是我上大学以来觉得最为困难的一次小学期,这一次的任务综合了信道系统编码和通信原理的知识与Matlab软件的应用。以前几乎没用过matlab,所以刚看到这个题目时我简直觉得我从下手。Ppt看了好多遍也不知道到底做什么。通过翻阅通原课本、上网查阅资料,了解ppt上给出的每个函数的功能与用途,经过两个星期终于完成了本次任务。在这次任务重,我碰到了许许多多的问题,其中最复杂的部分就是调制部分的代码与瑞利信道函数部分的代码。借助网上找的资料和在同学的帮助下才完成了这次的任务。这次小学期让我获益匪浅,首先我温习了通信原理的知识,而且学习了matlab的一些的用法。最开始的迷茫到最后的完成,感觉万事开头难,只要有足够的决心与毅力,没有什么是完成不了的。希望下一次我可以做的更好。
八、参考文献
吴伟陵,牛凯,《移动通信原理》,电子工业出版社。
张梧桐.MIMO通信技术导论[J].科学周刊,2013(5).
周炯槃、庞沁华、续大我、吴伟陵、杨鸿文《通信原理》,北京邮电大学出版社
啜钢、王文博、常永宇、全庆一《移动通信原理与系统》,北京邮电大学出版社
附录资料:不需要的可以自行删除
Pascal/C/C++语句对比(补充版)
一、Helloworld
先看三种语言的样例:
Pascal
begin
writeln(‘Helloworld’);
end.
C
#include<stdio.h>
intmain()
{
printf("Helloworld!\n");
return0;
}
C++
#include<iostream>
usingnamespacestd;
intmain()
{
cout<<"Helloworld!"<<endl;
return0;
}
从这三个程序可以看到一些最基本的东西。在Pascal中的begin和end,在C/C++里就是{};Pascal主程序没有返回值,而C/C++返回0(好像在C中可以为NULL)。在C/C++中,main函数以前的是头文件,样例中C为stdio.h,C++除了iostream还有第二行的usingnamespacestd,这个是打开命名空间的,NOIP不会考这个,可以不管,只要知道就行了。
此外说明注释单行用//,段落的话Pascal为{},C/C++为/**/。
**常用头文件(模板)
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<ctime>
#include<string>
usingnamespacestd;
intmain()
{
……
system(“pause”);
return0;
}
二、数据类型及定义
这里只列出常用的类型。
1、整型
Pascal
C/C++
范围
shortint
-
-128…127
integer
short
-32768…32767
longint
Int
-2147483648…2147483647
int64
longlong
-9223372036854775808…9223372036854775807
byte
-
0…255
word
unsignedshort
0…65535
longword
unsignedint
0…4294967295
qword
unsignedlonglong
0…18446744073709551615
**当对longlong变量赋值时,后要加LL
Longlongx=6327844632743269843LL
**如果位移x<<2LL
**Linux:printf(“%lld\n”,x);
**Windows:printf(“%I64d\n”,x);
2、实型
Pascal
C/C++
范围
real
float
2.9E-39…1.7E38
single
-
1.5E-45…3.4E38
double
double
5.0E-324…1.7E308
3、字符即字符串
字符在三种语言中都为char,C里没有字符串,只有用字符数组来代替字符串,Pascal和C++均为string。Pascal中字符串长度有限制,为255,C++则没有。
字符串和字符在Pascal中均用单引号注明,在C/C++中字符用单引号,字符串用双引号。
4、布尔类型
Pascal中为boolean,C/C++为bool。值均为True或False。C/C++中除0外bool都为真。
5、定义
常量的定义均为const,只是在C/C++中必须要注明常量的类型。在C/C++中还可以用宏来定义常量,此时不注明类型。
Pascal
C/C++
const
a=60;
b=-a+30;
d=‘‘;
constinta=60;
constintb=-a+30;
conststringd=“”;
defineMAXN501//这个是宏
**宏定义其实就是直接在程序相应的位置替换:
#definerandomizesrand(unsignedtime(NULL))
#definewaitfor(intw=0;w<100000;w++)
变量的定义,C/C++在定义的同时可以赋值:
Pascal
C/C++
var
a,b:integer;
c:char;
d:string;
inta,b=50;
charc=‘A’;
stringd;
boolflag;
三、输入输出
C/C++中没有以回车作为结束的读入方式(就本人所知)。”\n”表示换行。常规输入输出:
Pascal
C
C++
read(a);//读入变量a
readln(a);//读入变a,回车结束
write(a);//输出a
writeln(a);//输出a并换行
scanf(“%d”,&a);
printf(“%d”,a);
printf(“%d\n”,a);
cin>>a;
cout<<a;
cout<<a<<endl;
特别说明C++中cin一个字符的话会自动跳过空格和回车,Pascal和C则会读入空格和回车。在Pascal中writeln(a:n:m)表示在n个字符宽的输出域上输出a保留m位小数。
例如:pascalwrite(a:6)c/c++printf(“%6d”,a)
Pascalwrite(a:6:2)c/c++printf(“%6.2f”,a)
C++如果用cout?(繁琐!!)
需要加头文件#inlude<iomanip>
cout<<setprecision(2)<<a;//作用永久
cout<<setw(6)<<a;//作用临时
以下三个进制设定都是永久作用:
cout<<dec<<a;相当printf(“%d”,a);//十进制
cout<<hex<<a;相当printf(“%X”,a);//十六进制
cout<<oct<<a;相当printf(“%o”,a);//八进制
例如:cout<<12<<hex<<12<<oct<<12<<12<<endl;
输出:12c1414
C的输入输出里面的字符串中%表示变量,%后面的字目表示变量类型。下面是类型表:
%hd
1个short型整数
%d
1个int型整数
%u
1个unsignedint型整数
%I64d
1个longlong型整数
%c
1个字符
%s
1个C字符串
%f
1个float型实数
%lf
1个double型实数
%10.4f
输出1个总宽度为10,保留4位小数的实数
文件输入输出:
Pascal
assign(input,‘test.in’);
assign(output,‘test.out’);
reset(input);
rewrite(output);
read(a,b);
writeln(a,b);
close(input);
close(output);
C
FILE*fin=fopen(“test.in”,“r”);
FILE*fout=fopen(“test.out”,“w”);
fscanf(fin,“%d%d”,&a,&b);
fprintf(fout,“%d%d”,a,b);
fclose(fin);
fclose(fout);
C++
#include<fstream>
usingnamespacestd;
ifstreamfin(“test.in”);
ofstreamfout(“test.out”);
fin>>a>>b;
fout<<a<<b<<endl;
fin.close();
fout.close();
因为C++的读入较慢,个人建议C++的话使用C的输入方式。当然也有人用C的读入,C++的输出的,这种方式我们称之为城乡结合。
**中国计算机学会竞赛须知发布的C读写程序:
(C++也能用,cin,cout,scanf,printf可混用)
#include<stdio.h>
intmain()
{
inta,b;
freopen(“sum.in”,”r”,stdin);
freopen(“sum.out”,”w”,stdout);
scanf(“%d%d”,&a,&b);
printf(“%d\n”,a+b);
return0;
}
或者:
freopen(“sum.in”,”r”,stdin);
freopen(“sum.out”,”w”,stdout);
ios::sync_with_stdio(false);\\取消同步,cin,cout的速度就不慢了!!
cin>>a>>b;
cout<<a+b<<endl;
return0;
以下扩充c/c++混用是可行的:
#include<iostream>
#include<cstdio>
usingnamespacestd;
intmain()
{
inta,b,c,d;
freopen("sum.in","r",stdin);
freopen("sum.out","w",stdout);
scanf("%d%d",&a,&b);
cin>>c>>d;
printf("%d\n",a+b);
cout<<a+b+c+d<<endl;
return0;
}
**如何判断文件结束(EOF)?
C++
while(cin>>s>>n)
{
...
}
C
while(scanf(%s%d",s,&n)!=EOF)
{
...
}
四、赋值语句及运算符号
一一对应的关系
Pascal
C/C++
赋值运算
赋值
:=
=
基本运算
加
+
+
减
-
-
乘
*
*
除(实数)
/
/(double)
除法
取整
div
(int)/(int)
取余
mod
%
比较
等于
=
==
不等于
<>
!=
大于
>
>
大于等于
>=
>=
小于
<
<
小于等于
<=
<=
逻辑
且
and
&&
或
or
||
非
not
!
位运算
左移(*2)
shl
<<
右移(/2)
shr
>>
且
and
&
或
or
|
非
not
~
异或
xor
^
其他
增一
inc(x)
x++
减一
dec(x)
x--
在C/C++中对某个变量自身进行运算可以简写为
变量名运算符号=改变量
如x+=8就表示x=x+8,即inc(x,8)。
在C/C++里还存在一种三目运算
变量名=条件?值A:值B
如x=x>0?x:-x;//表示若x>0则取x,否则取–x,
同ifx>0thenx:=xelsex:=-x;
五、条件语句
1、if
C/C++中if语句的条件必须要用括号括起来,后面不使用then。
Pascal
C/C++
ifa>bthenflag:=true
elseflag:=false;
if(a>b)flag=true;
elseflag=false;
2、多种分支
C/C++中为switch,Pascal为case:
Pascal
C/C++
casexof
1:inc(x);
2:dec(x);
elsex:=x*x;
end;
switch(x)
{
case1:x++;break;
case2:x--;break;
default:x*=x;
}
切记C/C++中一定要写break,后果你可以去掉break,运行看看就知道了。
六、循环语句
1、for
Pascal
C/C++
for变量名:=初始值to(downto)终止值do
for(变量名=初始值;条件;改变方式)
fori:=5to10dodec(a);
//终止值大于初始值用to
fori:=5downto1dodec(a);
//终止值小于于初始值用downto
for(i=5;i<=10;i++)a--;
for(i=5;i>=1;i--)a--;
/*只要i满足条件就会一直循环。
C/C++中i是实数、指针都可以*/
C/C++中for的特殊用法:
//变量为实数
for(doublei=1;i<=2;i*=1.01)
k++;
//变量为指针,->符号为间接引用,后面会提到。
for(type1*p=head->next;p;p=p->next)
printf(“%d”,p->k);
2、while
Pascal
C/C++
while条件do
while(条件)
whilei<>0dodec(i);
while(i!=0)i--;
//也可写作while(i)i--;
//在C/C++中非0即为真。
3、repeat-until&do-while
Pascal
C/C++
repeat语句until结束条件;
do{}while(运行条件)
repeatint(i)untili>100;
do{i++;}while(i<=100);
七、数组
Pascal中数组的下标可以随意定义,而C/C++下标始终为从0开始到(数组大小–1)。
Pascal
C/C++
定义
a:array[1..100]ofinteger;
b:array[1..10,1..10]ofint64;
inta[100];
intb[10][10];
含义
a为大小为100的integer数组,合法下标为1到100
b为大小为10*10的int64数组,合法下标为1,1到10,10
a为大小为100的int数组,合法下标为0到99
b为大小为10*10的int数组,合法下标为0,0到9,9;
使用
inc(a[21]);
b[2,2]:=b[1,1]+b[1,2]+b[2,1];
a[21]++;
b[1][1]=b[0][1]+b[0][0]+b[1][0];
数组清零
Pascal
C/C++
Fillchar(a,sizeof(a),0);
memset(a,0,sizeof(a));
//头文件包含string.h
**如果要填最大:memset(a,127,sizeof(a))(但达不到INT_MAX)
如果要填最小:memset(a,128,sizeof(a))(但达不到INT_MIN)
如果填0:memset(a,0,sizeof(a))
如果填-1:memset(a,-1,sizeof(a))
八、字符串
C风格的字符串就是字符数组。
C++和Pascal的字符串使用基本相同,只是C++中字符串下标以0开始,Pascal以1开始。字符串处理很多这里不一一列举,只写最常用的几个。
Pascal
C(包含<string.h>)
定义用:chars[]
C++(包含<string>)
定义用:strings
输入
输
出
Readln(s);
Writeln(s);
Scanf(“%s”,s);
Printf(“%s\n”,s);
注:不能输入输出c++的字符串
Cin>>s;
Cout<<s<<endl;
注:可以输入输出c的字符串
查找
pos(‘a’,s);//不存在返回0
没有
s.find(‘a’);//不存在返回-1
串
长
len=length(s);
Strlen(s)
len=s.size();或
Len=s.length();
复制
copy(st,pos,num);
st:=‘abcde’;
s:=copy(st,3,2);
//s=‘cd’
Strcpy(s1,s2)
全部复制
Strncpy(s1,s2,n)
前n个复制
但没有从第几个开始的!
substr(pos,n)//返回从pos开始的长度为n的子串;
strings1=“abcde”,s2;
s2=s1.substr(2,2);
//s2=“cd”
插入
insert(obj,target,pos);
st:=‘helloworld’;
st:=insert(‘‘,st,6);
//st=‘helloworld’
没有
insert(pos,s)//在pos位置处插入字符串s;
strings1=“0123”;
s1.insert(1,“XYZ”);//s1=“0XYZ123”
删除
delete(st,pos,num);
st:=‘helloworld’;
st:=delete(st,6,1);
//st=‘helloworld’
没有
erase(pos,n)//从pos位置开始删除n个字符;
strings1="abcdefghi";
s1.erase(5,3);//得到"abcdei"
C++还有以下功能:
用s.replace(2,2,"ttt")可以部分替换
用s.empty()判断是否为空
可访问s[i],位置从0算起
可以s1+s2
可以s1=s2
可以比较s1==s2当然><=>=<=!=都可以比较。
C++字符串整串读入:
getline(cin,s)和cin>>s的区别:
getline(cin,s)
cin>>s
一次性整行读入,直至行末尾。
只读入一个“单词”,遇空格和行末停止。
例如输入;Howareyou?
s=”Howareyou?”
读入整串含空格
例如输入;Howareyou?
s=”How”
如果三个都读:cin>>s1>>s2>>s3
**C++数字与数值之间的转换:
#include<iostream>
#include<string>
#include<sstream>//必须加入
usingnamespacestd;
intmain()
{
stringtext="152";
intnumber;
stringstreamss;
ss<<text;//可以是其他数据类型
ss>>number;//string->int
cout<<number+100<<endl;
ss<<number;//int->string
stringstr=ss.str();
return0;
}
九、过程和函数
1、过程
在C/C++中没有过程,但可以把返回值为“空”的函数理解为过程。
Pascal
C/C++
无参过程
procedure过程名;
说明部分
begin语句部分end;
//说明部分、begin、end语句部分统称为过程体
void函数名();
{
主体部分;
return;
}
带参过程
procedure过程名(形参表)
过程体
void函数名(形参表)
过程体
值传和址传:当一个参数是值传时,形参在子过程中相当于一个局部变量,对它的改变不影响实在的参数值。址传则会影响。下例中a为值传,b为址传。初始a=5,b=5,运行后a=5,b=10;
Pascal
C/C++
vara,b:integer;
proceduredoit(a:integer;varb:integer);
begin
b:=a+b;
a:=a+b;
end;
begin
a:=5;
b:=5;
doit(a,b);
writeln(a,‘‘,b);
end.
voiddoit(inta,int&b)
{
\\a
认为值参,b认为变量传参
b+=a;
a+=b;
return;
}
intmain()
{
inta=5,b=5;
doit(a,b);
cout<<a<<‘‘<<b;
return0;
}
**用若干地址传参可以给调用者传回若干值
Voidtryit(int&x,int&y,int&z)
调用时:tryit(a,b,c),可以传回a,b,c的值。
**用数组名(也是地址)传参可以传回整组的数据
Voidtryit(inta[])
调用时:tryit(x),可以传回整个数组。
例如:
voidtryit(inta[])
{
for(inti=0;i<=10;i++)a[i]=i*2;
return;
}
intmain()
{
intx[10];
tryit(x);
for(inti=0;i<=10;i++)
cout<<x[i]<<endl;
system("pause");
return0;
}
**用指向函数的指针作为参数,可以执行指定的函数。(略)
STL的两个应用:
**C++快排函数
#include<algorithm>
Boolcom(inta,intb)
{
Returna>b;
}
Intmain()
{
Inta[10]={5,7,3,2,6,8,4,3,5,7};
Sort(a,a+10,com);//如果升序可以省略com.
For(inti=0;i<10;i++)
Cout<<a[i]<<”“;
}
**优先队列(以堆排为例)
#include<iostream>
#include<queue>
usingnamespacestd;
priority_queue<int>Q;
intmain()
{
intn,a;
cin>>n;
while(n--)
{
cin>>a;
Q.push(a);
}
while(!Q.empty())
{
cout<<Q.top()<<"";
Q.pop();
}
return0;
}
**队列、栈、优先队列三种数据结构汇总:
#include<queue>
#include<stack>
priority_queue<int>Q;
queue<int>Q1;
stack<int>S;
intmain()
{
Q.push(5);x=Q.top();Q.pop();Q.empty();Q.size()
Q1.push(5);Q1.size();Q1.front();Q1.em
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 阿里巴巴基础知识
- 民用电脑购销合同(标准版)
- 高二理科英语月考卷附答案
- 高二选修4月考卷
- 八年级月考卷
- 30种市集摊位美陈+非遗文化美食+非遗文化互动整合营销方案
- 《中西医结合治疗 1 例高龄顽固性便秘患者的护理体会》
- 《1 例重症乙型脑炎的个案护理》
- TTAF 246-2024 智能终端未成年视健康安全防护规范
- 二手机动车买卖契约(标准版)
- 新基础教育研究下的数运算教学
- 锥坡工程量计算
- 胎膜早破护理个案完整版
- DB4228∕T 24-2021 包装用箬叶
- 化妆品微生物检验原始记录
- 《社会政策》课件第四章社会政策与人的需要及社会问题
- 人教版小学三年级《道德与法治》上册课件(全册)
- (脓毒血症)护理查房
- 旅游财务管理—财务管理的基本理念
- 锅炉房设计施工运行规范要求
- 天然橡胶产业园项目可行性研究报告
评论
0/150
提交评论