实际应用中好像不广泛哦?
16 个解决方案
#1
有请高手指教!
#2
#include "list"
useing namespace std
list<int> aa;//链表你的数据结构好像意义减少了
aa.pushback(3330)
aa.pushback(123)
aa.pushbakc(343)
qsort(aa)//快速排序
cout<<aa;
简单的快速排序,
useing namespace std
list<int> aa;//链表你的数据结构好像意义减少了
aa.pushback(3330)
aa.pushback(123)
aa.pushbakc(343)
qsort(aa)//快速排序
cout<<aa;
简单的快速排序,
#3
高手啊!
#4
: 如何用vector申请一个多维数组
主要解答者: prototype 提交人: hellwolf
感谢: babysloth、prototype、nhsoft
审核者: babysloth 论坛对应贴子: 查看
A :
如何用vector申请一个多维数组(n)
---------------------------------------------------------------
vector<vector<int> >如何?
---------------------------------------------------------------
三维数组,用vector实现
vector< vector< vector<int > > > a;
如果象afsfop那样写,
std::vector<int> vec[2][2];
vec[0][0][0]=1;
cout<<vec[0][0][0];
---------------------------------------------------------------
那句a[0][0][0]=1;应该改成a[0][0].push_back(1);
不能直接赋值,还没分配空间呢^_^
---------------------------------------------------------------
提起数组,大家想必都很熟悉,你可以用索引和指针来操作数组,给程序设计带来了很大的灵活性。但是你知道它有许多天生的缺陷吗?
首先,数组的越界可能会引起程序的崩溃(如果崩溃了,还算你走运^_^)。其次是动态性不好,包括动态改变大小,动态申请。诸如此类的事,一定会让你伤透脑筋。有什么办法可以解决这些问题吗?
你不用担心,下面我来给大家介绍一种方法:用vector取代C-style的数组。
关于vector我不想多说,我假设大家都了解temlplate 和 STL。各位在任何一本C++的书上都可以找的到这些内容的(如果没有,那赶快把它扔掉)。那为什么是vector呢?我们知道vector提供了operator[]函数,可以像数组一样的操作,而且还有边界检查,动态改变大小。(从这点上deque也是可以的)。vector本来就是可以用来代替一维数组的,这里只介绍用它来代替二维的数组。二维以上的可以依此类推。
我们知道,C++的template参数是可以嵌套定义的,你可以这样定义一个模板的Instance
vector<vector<int> > array2(3);//注意>和>之间的空格。
这就是我们的关键,array2可以保存3个向量,向量的长度是可以改变的。array2[i]返回的是第i个向量。同理,array2[i][j]返回的是第i个向量中的第j个元素。
到这里,你可能会得意的说:"我明白了,很简单吗!"。别急,还有一些细节问题:如下
vector<vector<int> > array2(3);
array2[1][2]=9;
我保证你的程序会segement failed,原因就是你没有指定向量的大小。用push_back函数可以解决问题:array2[1].push_back(9);但是好象不太爽。就不能用operator[]吗?答案是肯定的。不过要多加几个步骤,如下:
for(int i=0;i<3;i++)
array2[i].resize(3);
这样,你就定义了一个3X3的数组了(另一个3在 申明时定义的)。而且你可以随时改变它的大小。
其他的,你还可以用C++的异常机制来捕获如下标越界等非法行为。进行必要的处理。使你的程序更加的健壮。具体的方法我就不深入介绍了。留给各位自己钻研。下面提供一个范例,供参考。
//用vector来代替数组
// 潘李亮2002-1-13
//在GNU c++ Mandrake Linux7.0下通过,
//在VC下会有变量定义问题,大家自己解决
#include <iostream>
#include <vector>
using namespace std;
void main()
{
vector< vector<int> > array(3);
for(int i=0;i<3;i++)
array[i].resize(3);//设置数组的大小3X3
//现在你可以和使用数组一样使用这个vector
for(int i=0;i<3;i++)
for(int j=0;j<3;j++)
array[i][j]=(i*j);
//输出
for(int i=0;i<3;i++)
{
for(int j=0;j<3;j++)
cout<<array[i][j]<<" ";
cout<<endl;
}
array.resize(5);
arry[3].resize(3);
arry[4].resize(3);
//现在是5X3的数组了
for(int i=0;i<5;i++)
for(int j=0;j<3;j++)
array[i][j]=(i*j);
for(int i=0;i<5;i++)
{
for(int j=0;j<3;j++)
cout<<array[i][j]<<" ";
cout<<endl;
}
}
声明:不是我写的啊!
主要解答者: prototype 提交人: hellwolf
感谢: babysloth、prototype、nhsoft
审核者: babysloth 论坛对应贴子: 查看
A :
如何用vector申请一个多维数组(n)
---------------------------------------------------------------
vector<vector<int> >如何?
---------------------------------------------------------------
三维数组,用vector实现
vector< vector< vector<int > > > a;
如果象afsfop那样写,
std::vector<int> vec[2][2];
vec[0][0][0]=1;
cout<<vec[0][0][0];
---------------------------------------------------------------
那句a[0][0][0]=1;应该改成a[0][0].push_back(1);
不能直接赋值,还没分配空间呢^_^
---------------------------------------------------------------
提起数组,大家想必都很熟悉,你可以用索引和指针来操作数组,给程序设计带来了很大的灵活性。但是你知道它有许多天生的缺陷吗?
首先,数组的越界可能会引起程序的崩溃(如果崩溃了,还算你走运^_^)。其次是动态性不好,包括动态改变大小,动态申请。诸如此类的事,一定会让你伤透脑筋。有什么办法可以解决这些问题吗?
你不用担心,下面我来给大家介绍一种方法:用vector取代C-style的数组。
关于vector我不想多说,我假设大家都了解temlplate 和 STL。各位在任何一本C++的书上都可以找的到这些内容的(如果没有,那赶快把它扔掉)。那为什么是vector呢?我们知道vector提供了operator[]函数,可以像数组一样的操作,而且还有边界检查,动态改变大小。(从这点上deque也是可以的)。vector本来就是可以用来代替一维数组的,这里只介绍用它来代替二维的数组。二维以上的可以依此类推。
我们知道,C++的template参数是可以嵌套定义的,你可以这样定义一个模板的Instance
vector<vector<int> > array2(3);//注意>和>之间的空格。
这就是我们的关键,array2可以保存3个向量,向量的长度是可以改变的。array2[i]返回的是第i个向量。同理,array2[i][j]返回的是第i个向量中的第j个元素。
到这里,你可能会得意的说:"我明白了,很简单吗!"。别急,还有一些细节问题:如下
vector<vector<int> > array2(3);
array2[1][2]=9;
我保证你的程序会segement failed,原因就是你没有指定向量的大小。用push_back函数可以解决问题:array2[1].push_back(9);但是好象不太爽。就不能用operator[]吗?答案是肯定的。不过要多加几个步骤,如下:
for(int i=0;i<3;i++)
array2[i].resize(3);
这样,你就定义了一个3X3的数组了(另一个3在 申明时定义的)。而且你可以随时改变它的大小。
其他的,你还可以用C++的异常机制来捕获如下标越界等非法行为。进行必要的处理。使你的程序更加的健壮。具体的方法我就不深入介绍了。留给各位自己钻研。下面提供一个范例,供参考。
//用vector来代替数组
// 潘李亮2002-1-13
//在GNU c++ Mandrake Linux7.0下通过,
//在VC下会有变量定义问题,大家自己解决
#include <iostream>
#include <vector>
using namespace std;
void main()
{
vector< vector<int> > array(3);
for(int i=0;i<3;i++)
array[i].resize(3);//设置数组的大小3X3
//现在你可以和使用数组一样使用这个vector
for(int i=0;i<3;i++)
for(int j=0;j<3;j++)
array[i][j]=(i*j);
//输出
for(int i=0;i<3;i++)
{
for(int j=0;j<3;j++)
cout<<array[i][j]<<" ";
cout<<endl;
}
array.resize(5);
arry[3].resize(3);
arry[4].resize(3);
//现在是5X3的数组了
for(int i=0;i<5;i++)
for(int j=0;j<3;j++)
array[i][j]=(i*j);
for(int i=0;i<5;i++)
{
for(int j=0;j<3;j++)
cout<<array[i][j]<<" ";
cout<<endl;
}
}
声明:不是我写的啊!
#5
在嵌入式领域,很大啊
那还得看那些编译器支持不支持STL。
在wince, vst3.0中就不支持STL
那还得看那些编译器支持不支持STL。
在wince, vst3.0中就不支持STL
#6
up
#7
我们公司做嵌入式开发,全用的是C+汇编程
好象从没有用过C++
好象从没有用过C++
#8
听别人说,国内很少用!
国外很多用!
国外很多用!
#9
我所知道的。ARM的ADS里面的C++编译器,也支持STL。
因此如果你使用的是ARM的CPU,而且买了ADS的话,
也是可以用STL的。
因此如果你使用的是ARM的CPU,而且买了ADS的话,
也是可以用STL的。
#10
曾经看了不知那里的大虾写的文章:《嵌入式实时程序设计中C/C++代码的优化》,吓得我就不敢用了!
#11
转贴:嵌入式实时程序设计中C/C++代码的优化
1 引言
计算机技术和信息技术的高速发展的今天,计算机和计算机技术大量应用在人们的日常生活中,嵌入式计算机也得到了广泛的应用。
嵌入式计算机是指完成一种或多种特定功能的计算机系统,是软硬件的紧密结合体。具有软件代码小、高度自动化、响应速度快等特点。
特别适合于要求实时和多任务的应用体系。嵌入式实时系统是目前蓬勃发展的行业之一。
但是,实时嵌入式系统的特点使得其软件受时间和空间的严格限制,加上运行环境复杂,使得嵌入式系统软件的开发变得异常困难。
为了设计一个满足功能、性能和死线要求的系统,为了开发出安全可靠的高性能嵌入式系统,开发语言的选择十分重要。
2 嵌入式实时程序设计中语言的选择
随着嵌入式系统应用范围的不断扩大和嵌入式实时操作系统RTOS(Real Time Operating System)的广泛使用,高级语言编程已是嵌入
式系统设计的必然趋势。因为汇编语言和具体的微处理器的硬件结构密切相关,移植性较差,既不宜在复杂系统中使用,又不便于实现软
件重用;而高级语言具有良好的通用性和丰富的软件支持,便于推广、易于维护,因此高级语言编程具有许多优势。目前,在嵌入式系统
开发过程中使用的语言种类很多,但仅有少数几种语言得到了比较广泛的应用。其中C和C++是应用最广泛的。C++在支持现代软件工程、
OOP(Object Oriented Programming,面向对象的程序设计)、结构化等方面对C进行了卓有成效的改进,但在程序代码容量、执行速度、
程序复杂程度等方面比C语言程序性能差一些。由于C语言既有低级语言的直接控制硬件的能力,又有高级语言的灵活性,是目前在嵌入式
系统中应用最广泛的编程语言。随着网络技术和嵌入式技术的不断发展,Java的应用也得到广泛应用。
3 C/C++代码在实时程序设计中的优化
虽然使软件正确是一个工程合乎逻辑的最后一个步骤,但是在嵌入式的系统开发中,情况并不总是这样的。出于对低价产品的需求,
硬件的设计者需要提供刚好足够的存储器和完成工作的处理能力。所以在嵌入式软件设计的最后一个阶段则变成了对代码的优化。
现代的C和C++编译器都提供了一定程度上的代码优化。然而,大部分由编译器执行的优化仅涉及执行速度和代码大小的一个平衡。你
的程序能够变得更快或者更小,但是不可能又变快又变小。经过本人在嵌入式系统设计和实现过程中实践,下面介绍几种简单且行之有效
的C /C++代码的优化方法。
1.Inline函数
在C++中,关键字Inline可以被加入到任何函数的声明中。这个关键字请求编译器用函数内部的代码替换所有对于指出的函数的调用。
这样做在两个方面快于函数调用。这样做在两个方面快于函数调用:第一,省去了调用指令需要的执行时间;第二,省去了传递变元和传
递过程需要的时间。但是使用这种方法在优化程序速度的同时,程序长度变大了,因此需要更多的ROM。使用这种优化在Inline函数频繁调
用并且只包含几行代码的时候是最有效的。
2.用指针代替数组
在许多种情况下,可以用指针运算代替数组索引,这样做常常能产生又快又短的代码。与数组索引相比,指针一般能使代码速度更快,
占用空间更少。使用多维数组时差异更明显。下面的代码作用是相同的,但是效率不一样。
数组索引 指针运算
For(;;){ p=array
A=array[t++]; for(;;){
a=*(p++);
...... ......
} }
指针方法的优点是,array的地址每次装入地址p后,在每次循环中只需对p增量操作。在数组索引方法中,每次循环中都必须进行基于
t值求数组下标的复杂运算。
3.不定义不使用的返回值
function函数定义并不知道函数返回值是否被使用,假如返回值从来不会被用到,应该使用void来明确声明函数不返回任何值。
4.手动编写汇编
在嵌入式软件开发中,一些软件模块最好用汇编语言来写,这可以使程序更加有效。虽然C/C++编译器对代码进行了优化,但是适当的
使用内联汇编指令可以有效的提高整个系统运行的效率。
5.使用寄存器变量
在声明局部变量的时候可以使用register关键字。这就使得编译器把变量放入一个多用途的寄存器中,而不是在堆栈中,合理使用这
种方法可以提高执行速度。函数调用越是频繁,越是可能提高代码的速度。
6.使用增量和减量操作符
在使用到加一和减一操作时尽量使用增量和减量操作符,因为增量符语句比赋值语句更快,原因在于对大多数CPU来说,对内存字的增、
减量操作不必明显地使用取内存和写内存的指令,比如下面这条语句:
x=x+1;
模仿大多数微机汇编语言为例,产生的代码类似于:
move A,x ;把x从内存取出存入累加器A
add A,1 ;累加器A加1
store x ;把新值存回x
如果使用增量操作符,生成的代码如下:
incr x ;x加1
显然,不用取指令和存指令,增、减量操作执行的速度加快,同时长度也缩短了。
7.减少函数调用参数
使用全局变量比函数传递参数更加有效率。这样做去除了函数调用参数入栈和函数完成后参数出栈所需要的时间。然而决定使用全局
变量会影响程序的模块化和重入,故要慎重使用。
8.Switch语句中根据发生频率来进行case排序
switch语句是一个普通的编程技术,编译器会产生if-else-if的嵌套代码,并按照顺序进行比较,发现匹配时,就跳转到满足条件的
语句执行。使用时需要注意。每一个由机器语言实现的测试和跳转仅仅是为了决定下一步要做什么,就把宝贵的处理器时间耗尽。为了提
高速度,没法把具体的情况按照它们发生的相对频率排序。换句话说,把最可能发生的情况放在第一位,最不可能的情况放在最后。
9.将大的switch语句转为嵌套switch语句
当switch语句中的case标号很多时,为了减少比较的次数,明智的做法是把大switch语句转为嵌套switch语句。把发生频率高的case
标号放在一个switch语句中,并且是嵌套switch语句的最外层,发生相对频率相对低的case标号放在另一个switch语句中。比如,下面的
程序段把相对发生频率低的情况放在缺省的case标号内。
pMsg=ReceiveMessage();
switch (pMsg->type)
{
case FREQUENT_MSG1:
handleFrequentMsg();
break;
case FREQUENT_MSG2:
handleFrequentMsg2();
break;
......
case FREQUENT_MSGn:
handleFrequentMsgn();
break;
default: //嵌套部分用来处理不经常发生的消息
switch (pMsg->type)
{
case INFREQUENT_MSG1:
handleInfrequentMsg1();
break;
case INFREQUENT_MSG2:
handleInfrequentMsg2();
break;
......
case INFREQUENT_MSGm:
handleInfrequentMsgm();
break;
}
}
如果switch中每一种情况下都有很多的工作要做,那么把整个switch语句用一个指向函数指针的表来替换会更加有效,比如下面的
switch语句,有三种情况:
enum MsgType{Msg1, Msg2, Msg3}
switch (ReceiveMessage()
{
case Msg1;
......
case Msg2;
.....
case Msg3;
.....
}
为了提高执行速度,用下面这段代码来替换这个上面的switch语句。
/*准备工作*/
int handleMsg1(void);
int handleMsg2(void);
int handleMsg3(void);
/*创建一个函数指针数组*/
int (*MsgFunction [])()={handleMsg1, handleMsg2, handleMsg3};
/*用下面这行更有效的代码来替换switch语句*/
status=MsgFunction[ReceiveMessage()]();
10.避免使用C++的昂贵特性
C++在支持现代软件工程、OOP、结构化等方面对C进行了卓有成效的改进,但在程序代码容量、执行速度、程序复杂程度等方面比C语
言程序性能差一些。并不是所有的C++特性都是肮贵的。比如,类的定义是完全有益的。公有和私有成员数据及函数的列表与一个struct及
函数原形的列表并没有多大的差别。单纯的加入类既不会影响代码的大小,也不会影响程序的效率。但C++的多重继承、虚拟基类、模板、
异常处理及运行类型识别等特性对代码的大小和效率有负面的影响,因此对于C++的一些特性要慎重使用,可做些实验看看它们对应用程序
的影响。
4 总结语
在嵌入式实时程序设计时可以运用上面介绍的一种或多种技术来优化代码。上面介绍的方法主要是为了提高代码的效率。但是事实上,
在使用这些技术提高代码运行速度的同时会相应的产生一些负面的影响,比如增加代码的大小、降低程序可读性等。不过你可以让C/C++编
译器来进行减少代码大小的优化,而手动利用以上技术来减少代码的执行时间。在嵌入式程序设计中合理地使用这几种技术有时会达到很好
的优化效果。
1 引言
计算机技术和信息技术的高速发展的今天,计算机和计算机技术大量应用在人们的日常生活中,嵌入式计算机也得到了广泛的应用。
嵌入式计算机是指完成一种或多种特定功能的计算机系统,是软硬件的紧密结合体。具有软件代码小、高度自动化、响应速度快等特点。
特别适合于要求实时和多任务的应用体系。嵌入式实时系统是目前蓬勃发展的行业之一。
但是,实时嵌入式系统的特点使得其软件受时间和空间的严格限制,加上运行环境复杂,使得嵌入式系统软件的开发变得异常困难。
为了设计一个满足功能、性能和死线要求的系统,为了开发出安全可靠的高性能嵌入式系统,开发语言的选择十分重要。
2 嵌入式实时程序设计中语言的选择
随着嵌入式系统应用范围的不断扩大和嵌入式实时操作系统RTOS(Real Time Operating System)的广泛使用,高级语言编程已是嵌入
式系统设计的必然趋势。因为汇编语言和具体的微处理器的硬件结构密切相关,移植性较差,既不宜在复杂系统中使用,又不便于实现软
件重用;而高级语言具有良好的通用性和丰富的软件支持,便于推广、易于维护,因此高级语言编程具有许多优势。目前,在嵌入式系统
开发过程中使用的语言种类很多,但仅有少数几种语言得到了比较广泛的应用。其中C和C++是应用最广泛的。C++在支持现代软件工程、
OOP(Object Oriented Programming,面向对象的程序设计)、结构化等方面对C进行了卓有成效的改进,但在程序代码容量、执行速度、
程序复杂程度等方面比C语言程序性能差一些。由于C语言既有低级语言的直接控制硬件的能力,又有高级语言的灵活性,是目前在嵌入式
系统中应用最广泛的编程语言。随着网络技术和嵌入式技术的不断发展,Java的应用也得到广泛应用。
3 C/C++代码在实时程序设计中的优化
虽然使软件正确是一个工程合乎逻辑的最后一个步骤,但是在嵌入式的系统开发中,情况并不总是这样的。出于对低价产品的需求,
硬件的设计者需要提供刚好足够的存储器和完成工作的处理能力。所以在嵌入式软件设计的最后一个阶段则变成了对代码的优化。
现代的C和C++编译器都提供了一定程度上的代码优化。然而,大部分由编译器执行的优化仅涉及执行速度和代码大小的一个平衡。你
的程序能够变得更快或者更小,但是不可能又变快又变小。经过本人在嵌入式系统设计和实现过程中实践,下面介绍几种简单且行之有效
的C /C++代码的优化方法。
1.Inline函数
在C++中,关键字Inline可以被加入到任何函数的声明中。这个关键字请求编译器用函数内部的代码替换所有对于指出的函数的调用。
这样做在两个方面快于函数调用。这样做在两个方面快于函数调用:第一,省去了调用指令需要的执行时间;第二,省去了传递变元和传
递过程需要的时间。但是使用这种方法在优化程序速度的同时,程序长度变大了,因此需要更多的ROM。使用这种优化在Inline函数频繁调
用并且只包含几行代码的时候是最有效的。
2.用指针代替数组
在许多种情况下,可以用指针运算代替数组索引,这样做常常能产生又快又短的代码。与数组索引相比,指针一般能使代码速度更快,
占用空间更少。使用多维数组时差异更明显。下面的代码作用是相同的,但是效率不一样。
数组索引 指针运算
For(;;){ p=array
A=array[t++]; for(;;){
a=*(p++);
...... ......
} }
指针方法的优点是,array的地址每次装入地址p后,在每次循环中只需对p增量操作。在数组索引方法中,每次循环中都必须进行基于
t值求数组下标的复杂运算。
3.不定义不使用的返回值
function函数定义并不知道函数返回值是否被使用,假如返回值从来不会被用到,应该使用void来明确声明函数不返回任何值。
4.手动编写汇编
在嵌入式软件开发中,一些软件模块最好用汇编语言来写,这可以使程序更加有效。虽然C/C++编译器对代码进行了优化,但是适当的
使用内联汇编指令可以有效的提高整个系统运行的效率。
5.使用寄存器变量
在声明局部变量的时候可以使用register关键字。这就使得编译器把变量放入一个多用途的寄存器中,而不是在堆栈中,合理使用这
种方法可以提高执行速度。函数调用越是频繁,越是可能提高代码的速度。
6.使用增量和减量操作符
在使用到加一和减一操作时尽量使用增量和减量操作符,因为增量符语句比赋值语句更快,原因在于对大多数CPU来说,对内存字的增、
减量操作不必明显地使用取内存和写内存的指令,比如下面这条语句:
x=x+1;
模仿大多数微机汇编语言为例,产生的代码类似于:
move A,x ;把x从内存取出存入累加器A
add A,1 ;累加器A加1
store x ;把新值存回x
如果使用增量操作符,生成的代码如下:
incr x ;x加1
显然,不用取指令和存指令,增、减量操作执行的速度加快,同时长度也缩短了。
7.减少函数调用参数
使用全局变量比函数传递参数更加有效率。这样做去除了函数调用参数入栈和函数完成后参数出栈所需要的时间。然而决定使用全局
变量会影响程序的模块化和重入,故要慎重使用。
8.Switch语句中根据发生频率来进行case排序
switch语句是一个普通的编程技术,编译器会产生if-else-if的嵌套代码,并按照顺序进行比较,发现匹配时,就跳转到满足条件的
语句执行。使用时需要注意。每一个由机器语言实现的测试和跳转仅仅是为了决定下一步要做什么,就把宝贵的处理器时间耗尽。为了提
高速度,没法把具体的情况按照它们发生的相对频率排序。换句话说,把最可能发生的情况放在第一位,最不可能的情况放在最后。
9.将大的switch语句转为嵌套switch语句
当switch语句中的case标号很多时,为了减少比较的次数,明智的做法是把大switch语句转为嵌套switch语句。把发生频率高的case
标号放在一个switch语句中,并且是嵌套switch语句的最外层,发生相对频率相对低的case标号放在另一个switch语句中。比如,下面的
程序段把相对发生频率低的情况放在缺省的case标号内。
pMsg=ReceiveMessage();
switch (pMsg->type)
{
case FREQUENT_MSG1:
handleFrequentMsg();
break;
case FREQUENT_MSG2:
handleFrequentMsg2();
break;
......
case FREQUENT_MSGn:
handleFrequentMsgn();
break;
default: //嵌套部分用来处理不经常发生的消息
switch (pMsg->type)
{
case INFREQUENT_MSG1:
handleInfrequentMsg1();
break;
case INFREQUENT_MSG2:
handleInfrequentMsg2();
break;
......
case INFREQUENT_MSGm:
handleInfrequentMsgm();
break;
}
}
如果switch中每一种情况下都有很多的工作要做,那么把整个switch语句用一个指向函数指针的表来替换会更加有效,比如下面的
switch语句,有三种情况:
enum MsgType{Msg1, Msg2, Msg3}
switch (ReceiveMessage()
{
case Msg1;
......
case Msg2;
.....
case Msg3;
.....
}
为了提高执行速度,用下面这段代码来替换这个上面的switch语句。
/*准备工作*/
int handleMsg1(void);
int handleMsg2(void);
int handleMsg3(void);
/*创建一个函数指针数组*/
int (*MsgFunction [])()={handleMsg1, handleMsg2, handleMsg3};
/*用下面这行更有效的代码来替换switch语句*/
status=MsgFunction[ReceiveMessage()]();
10.避免使用C++的昂贵特性
C++在支持现代软件工程、OOP、结构化等方面对C进行了卓有成效的改进,但在程序代码容量、执行速度、程序复杂程度等方面比C语
言程序性能差一些。并不是所有的C++特性都是肮贵的。比如,类的定义是完全有益的。公有和私有成员数据及函数的列表与一个struct及
函数原形的列表并没有多大的差别。单纯的加入类既不会影响代码的大小,也不会影响程序的效率。但C++的多重继承、虚拟基类、模板、
异常处理及运行类型识别等特性对代码的大小和效率有负面的影响,因此对于C++的一些特性要慎重使用,可做些实验看看它们对应用程序
的影响。
4 总结语
在嵌入式实时程序设计时可以运用上面介绍的一种或多种技术来优化代码。上面介绍的方法主要是为了提高代码的效率。但是事实上,
在使用这些技术提高代码运行速度的同时会相应的产生一些负面的影响,比如增加代码的大小、降低程序可读性等。不过你可以让C/C++编
译器来进行减少代码大小的优化,而手动利用以上技术来减少代码的执行时间。在嵌入式程序设计中合理地使用这几种技术有时会达到很好
的优化效果。
#12
其实我也没有好好去看这些 “C++的昂贵特性”编译以后的代码?也没去做过效率测试!
我现在就是作ARM下面的旅馆管理系统!呵呵,好像硬件环境比较充裕哦!32M内存,64MFLASH
(还没确定),别人给我说内存大着呢!你尽管浪费好啦!只要快点给我完成!哀!没办法,我就只用了一大队数组完成了基本数据存储!
本来想用STL,但我还不熟悉,呵呵,没办法,只好自己写了简单的list来实现,不过心里总不踏实!!!
我现在就是作ARM下面的旅馆管理系统!呵呵,好像硬件环境比较充裕哦!32M内存,64MFLASH
(还没确定),别人给我说内存大着呢!你尽管浪费好啦!只要快点给我完成!哀!没办法,我就只用了一大队数组完成了基本数据存储!
本来想用STL,但我还不熟悉,呵呵,没办法,只好自己写了简单的list来实现,不过心里总不踏实!!!
#13
To:wwwer
ARM下面支持C++的环境有那些?
ARM下面支持C++的环境有那些?
#14
ARM公司自己出的ADS就支持C++
#15
还有一个什么EC++标准,我怀疑这是谁搞出来的?
#16
写得蛮好,赶快去改原来写过的代码,呵呵。
#1
有请高手指教!
#2
#include "list"
useing namespace std
list<int> aa;//链表你的数据结构好像意义减少了
aa.pushback(3330)
aa.pushback(123)
aa.pushbakc(343)
qsort(aa)//快速排序
cout<<aa;
简单的快速排序,
useing namespace std
list<int> aa;//链表你的数据结构好像意义减少了
aa.pushback(3330)
aa.pushback(123)
aa.pushbakc(343)
qsort(aa)//快速排序
cout<<aa;
简单的快速排序,
#3
高手啊!
#4
: 如何用vector申请一个多维数组
主要解答者: prototype 提交人: hellwolf
感谢: babysloth、prototype、nhsoft
审核者: babysloth 论坛对应贴子: 查看
A :
如何用vector申请一个多维数组(n)
---------------------------------------------------------------
vector<vector<int> >如何?
---------------------------------------------------------------
三维数组,用vector实现
vector< vector< vector<int > > > a;
如果象afsfop那样写,
std::vector<int> vec[2][2];
vec[0][0][0]=1;
cout<<vec[0][0][0];
---------------------------------------------------------------
那句a[0][0][0]=1;应该改成a[0][0].push_back(1);
不能直接赋值,还没分配空间呢^_^
---------------------------------------------------------------
提起数组,大家想必都很熟悉,你可以用索引和指针来操作数组,给程序设计带来了很大的灵活性。但是你知道它有许多天生的缺陷吗?
首先,数组的越界可能会引起程序的崩溃(如果崩溃了,还算你走运^_^)。其次是动态性不好,包括动态改变大小,动态申请。诸如此类的事,一定会让你伤透脑筋。有什么办法可以解决这些问题吗?
你不用担心,下面我来给大家介绍一种方法:用vector取代C-style的数组。
关于vector我不想多说,我假设大家都了解temlplate 和 STL。各位在任何一本C++的书上都可以找的到这些内容的(如果没有,那赶快把它扔掉)。那为什么是vector呢?我们知道vector提供了operator[]函数,可以像数组一样的操作,而且还有边界检查,动态改变大小。(从这点上deque也是可以的)。vector本来就是可以用来代替一维数组的,这里只介绍用它来代替二维的数组。二维以上的可以依此类推。
我们知道,C++的template参数是可以嵌套定义的,你可以这样定义一个模板的Instance
vector<vector<int> > array2(3);//注意>和>之间的空格。
这就是我们的关键,array2可以保存3个向量,向量的长度是可以改变的。array2[i]返回的是第i个向量。同理,array2[i][j]返回的是第i个向量中的第j个元素。
到这里,你可能会得意的说:"我明白了,很简单吗!"。别急,还有一些细节问题:如下
vector<vector<int> > array2(3);
array2[1][2]=9;
我保证你的程序会segement failed,原因就是你没有指定向量的大小。用push_back函数可以解决问题:array2[1].push_back(9);但是好象不太爽。就不能用operator[]吗?答案是肯定的。不过要多加几个步骤,如下:
for(int i=0;i<3;i++)
array2[i].resize(3);
这样,你就定义了一个3X3的数组了(另一个3在 申明时定义的)。而且你可以随时改变它的大小。
其他的,你还可以用C++的异常机制来捕获如下标越界等非法行为。进行必要的处理。使你的程序更加的健壮。具体的方法我就不深入介绍了。留给各位自己钻研。下面提供一个范例,供参考。
//用vector来代替数组
// 潘李亮2002-1-13
//在GNU c++ Mandrake Linux7.0下通过,
//在VC下会有变量定义问题,大家自己解决
#include <iostream>
#include <vector>
using namespace std;
void main()
{
vector< vector<int> > array(3);
for(int i=0;i<3;i++)
array[i].resize(3);//设置数组的大小3X3
//现在你可以和使用数组一样使用这个vector
for(int i=0;i<3;i++)
for(int j=0;j<3;j++)
array[i][j]=(i*j);
//输出
for(int i=0;i<3;i++)
{
for(int j=0;j<3;j++)
cout<<array[i][j]<<" ";
cout<<endl;
}
array.resize(5);
arry[3].resize(3);
arry[4].resize(3);
//现在是5X3的数组了
for(int i=0;i<5;i++)
for(int j=0;j<3;j++)
array[i][j]=(i*j);
for(int i=0;i<5;i++)
{
for(int j=0;j<3;j++)
cout<<array[i][j]<<" ";
cout<<endl;
}
}
声明:不是我写的啊!
主要解答者: prototype 提交人: hellwolf
感谢: babysloth、prototype、nhsoft
审核者: babysloth 论坛对应贴子: 查看
A :
如何用vector申请一个多维数组(n)
---------------------------------------------------------------
vector<vector<int> >如何?
---------------------------------------------------------------
三维数组,用vector实现
vector< vector< vector<int > > > a;
如果象afsfop那样写,
std::vector<int> vec[2][2];
vec[0][0][0]=1;
cout<<vec[0][0][0];
---------------------------------------------------------------
那句a[0][0][0]=1;应该改成a[0][0].push_back(1);
不能直接赋值,还没分配空间呢^_^
---------------------------------------------------------------
提起数组,大家想必都很熟悉,你可以用索引和指针来操作数组,给程序设计带来了很大的灵活性。但是你知道它有许多天生的缺陷吗?
首先,数组的越界可能会引起程序的崩溃(如果崩溃了,还算你走运^_^)。其次是动态性不好,包括动态改变大小,动态申请。诸如此类的事,一定会让你伤透脑筋。有什么办法可以解决这些问题吗?
你不用担心,下面我来给大家介绍一种方法:用vector取代C-style的数组。
关于vector我不想多说,我假设大家都了解temlplate 和 STL。各位在任何一本C++的书上都可以找的到这些内容的(如果没有,那赶快把它扔掉)。那为什么是vector呢?我们知道vector提供了operator[]函数,可以像数组一样的操作,而且还有边界检查,动态改变大小。(从这点上deque也是可以的)。vector本来就是可以用来代替一维数组的,这里只介绍用它来代替二维的数组。二维以上的可以依此类推。
我们知道,C++的template参数是可以嵌套定义的,你可以这样定义一个模板的Instance
vector<vector<int> > array2(3);//注意>和>之间的空格。
这就是我们的关键,array2可以保存3个向量,向量的长度是可以改变的。array2[i]返回的是第i个向量。同理,array2[i][j]返回的是第i个向量中的第j个元素。
到这里,你可能会得意的说:"我明白了,很简单吗!"。别急,还有一些细节问题:如下
vector<vector<int> > array2(3);
array2[1][2]=9;
我保证你的程序会segement failed,原因就是你没有指定向量的大小。用push_back函数可以解决问题:array2[1].push_back(9);但是好象不太爽。就不能用operator[]吗?答案是肯定的。不过要多加几个步骤,如下:
for(int i=0;i<3;i++)
array2[i].resize(3);
这样,你就定义了一个3X3的数组了(另一个3在 申明时定义的)。而且你可以随时改变它的大小。
其他的,你还可以用C++的异常机制来捕获如下标越界等非法行为。进行必要的处理。使你的程序更加的健壮。具体的方法我就不深入介绍了。留给各位自己钻研。下面提供一个范例,供参考。
//用vector来代替数组
// 潘李亮2002-1-13
//在GNU c++ Mandrake Linux7.0下通过,
//在VC下会有变量定义问题,大家自己解决
#include <iostream>
#include <vector>
using namespace std;
void main()
{
vector< vector<int> > array(3);
for(int i=0;i<3;i++)
array[i].resize(3);//设置数组的大小3X3
//现在你可以和使用数组一样使用这个vector
for(int i=0;i<3;i++)
for(int j=0;j<3;j++)
array[i][j]=(i*j);
//输出
for(int i=0;i<3;i++)
{
for(int j=0;j<3;j++)
cout<<array[i][j]<<" ";
cout<<endl;
}
array.resize(5);
arry[3].resize(3);
arry[4].resize(3);
//现在是5X3的数组了
for(int i=0;i<5;i++)
for(int j=0;j<3;j++)
array[i][j]=(i*j);
for(int i=0;i<5;i++)
{
for(int j=0;j<3;j++)
cout<<array[i][j]<<" ";
cout<<endl;
}
}
声明:不是我写的啊!
#5
在嵌入式领域,很大啊
那还得看那些编译器支持不支持STL。
在wince, vst3.0中就不支持STL
那还得看那些编译器支持不支持STL。
在wince, vst3.0中就不支持STL
#6
up
#7
我们公司做嵌入式开发,全用的是C+汇编程
好象从没有用过C++
好象从没有用过C++
#8
听别人说,国内很少用!
国外很多用!
国外很多用!
#9
我所知道的。ARM的ADS里面的C++编译器,也支持STL。
因此如果你使用的是ARM的CPU,而且买了ADS的话,
也是可以用STL的。
因此如果你使用的是ARM的CPU,而且买了ADS的话,
也是可以用STL的。
#10
曾经看了不知那里的大虾写的文章:《嵌入式实时程序设计中C/C++代码的优化》,吓得我就不敢用了!
#11
转贴:嵌入式实时程序设计中C/C++代码的优化
1 引言
计算机技术和信息技术的高速发展的今天,计算机和计算机技术大量应用在人们的日常生活中,嵌入式计算机也得到了广泛的应用。
嵌入式计算机是指完成一种或多种特定功能的计算机系统,是软硬件的紧密结合体。具有软件代码小、高度自动化、响应速度快等特点。
特别适合于要求实时和多任务的应用体系。嵌入式实时系统是目前蓬勃发展的行业之一。
但是,实时嵌入式系统的特点使得其软件受时间和空间的严格限制,加上运行环境复杂,使得嵌入式系统软件的开发变得异常困难。
为了设计一个满足功能、性能和死线要求的系统,为了开发出安全可靠的高性能嵌入式系统,开发语言的选择十分重要。
2 嵌入式实时程序设计中语言的选择
随着嵌入式系统应用范围的不断扩大和嵌入式实时操作系统RTOS(Real Time Operating System)的广泛使用,高级语言编程已是嵌入
式系统设计的必然趋势。因为汇编语言和具体的微处理器的硬件结构密切相关,移植性较差,既不宜在复杂系统中使用,又不便于实现软
件重用;而高级语言具有良好的通用性和丰富的软件支持,便于推广、易于维护,因此高级语言编程具有许多优势。目前,在嵌入式系统
开发过程中使用的语言种类很多,但仅有少数几种语言得到了比较广泛的应用。其中C和C++是应用最广泛的。C++在支持现代软件工程、
OOP(Object Oriented Programming,面向对象的程序设计)、结构化等方面对C进行了卓有成效的改进,但在程序代码容量、执行速度、
程序复杂程度等方面比C语言程序性能差一些。由于C语言既有低级语言的直接控制硬件的能力,又有高级语言的灵活性,是目前在嵌入式
系统中应用最广泛的编程语言。随着网络技术和嵌入式技术的不断发展,Java的应用也得到广泛应用。
3 C/C++代码在实时程序设计中的优化
虽然使软件正确是一个工程合乎逻辑的最后一个步骤,但是在嵌入式的系统开发中,情况并不总是这样的。出于对低价产品的需求,
硬件的设计者需要提供刚好足够的存储器和完成工作的处理能力。所以在嵌入式软件设计的最后一个阶段则变成了对代码的优化。
现代的C和C++编译器都提供了一定程度上的代码优化。然而,大部分由编译器执行的优化仅涉及执行速度和代码大小的一个平衡。你
的程序能够变得更快或者更小,但是不可能又变快又变小。经过本人在嵌入式系统设计和实现过程中实践,下面介绍几种简单且行之有效
的C /C++代码的优化方法。
1.Inline函数
在C++中,关键字Inline可以被加入到任何函数的声明中。这个关键字请求编译器用函数内部的代码替换所有对于指出的函数的调用。
这样做在两个方面快于函数调用。这样做在两个方面快于函数调用:第一,省去了调用指令需要的执行时间;第二,省去了传递变元和传
递过程需要的时间。但是使用这种方法在优化程序速度的同时,程序长度变大了,因此需要更多的ROM。使用这种优化在Inline函数频繁调
用并且只包含几行代码的时候是最有效的。
2.用指针代替数组
在许多种情况下,可以用指针运算代替数组索引,这样做常常能产生又快又短的代码。与数组索引相比,指针一般能使代码速度更快,
占用空间更少。使用多维数组时差异更明显。下面的代码作用是相同的,但是效率不一样。
数组索引 指针运算
For(;;){ p=array
A=array[t++]; for(;;){
a=*(p++);
...... ......
} }
指针方法的优点是,array的地址每次装入地址p后,在每次循环中只需对p增量操作。在数组索引方法中,每次循环中都必须进行基于
t值求数组下标的复杂运算。
3.不定义不使用的返回值
function函数定义并不知道函数返回值是否被使用,假如返回值从来不会被用到,应该使用void来明确声明函数不返回任何值。
4.手动编写汇编
在嵌入式软件开发中,一些软件模块最好用汇编语言来写,这可以使程序更加有效。虽然C/C++编译器对代码进行了优化,但是适当的
使用内联汇编指令可以有效的提高整个系统运行的效率。
5.使用寄存器变量
在声明局部变量的时候可以使用register关键字。这就使得编译器把变量放入一个多用途的寄存器中,而不是在堆栈中,合理使用这
种方法可以提高执行速度。函数调用越是频繁,越是可能提高代码的速度。
6.使用增量和减量操作符
在使用到加一和减一操作时尽量使用增量和减量操作符,因为增量符语句比赋值语句更快,原因在于对大多数CPU来说,对内存字的增、
减量操作不必明显地使用取内存和写内存的指令,比如下面这条语句:
x=x+1;
模仿大多数微机汇编语言为例,产生的代码类似于:
move A,x ;把x从内存取出存入累加器A
add A,1 ;累加器A加1
store x ;把新值存回x
如果使用增量操作符,生成的代码如下:
incr x ;x加1
显然,不用取指令和存指令,增、减量操作执行的速度加快,同时长度也缩短了。
7.减少函数调用参数
使用全局变量比函数传递参数更加有效率。这样做去除了函数调用参数入栈和函数完成后参数出栈所需要的时间。然而决定使用全局
变量会影响程序的模块化和重入,故要慎重使用。
8.Switch语句中根据发生频率来进行case排序
switch语句是一个普通的编程技术,编译器会产生if-else-if的嵌套代码,并按照顺序进行比较,发现匹配时,就跳转到满足条件的
语句执行。使用时需要注意。每一个由机器语言实现的测试和跳转仅仅是为了决定下一步要做什么,就把宝贵的处理器时间耗尽。为了提
高速度,没法把具体的情况按照它们发生的相对频率排序。换句话说,把最可能发生的情况放在第一位,最不可能的情况放在最后。
9.将大的switch语句转为嵌套switch语句
当switch语句中的case标号很多时,为了减少比较的次数,明智的做法是把大switch语句转为嵌套switch语句。把发生频率高的case
标号放在一个switch语句中,并且是嵌套switch语句的最外层,发生相对频率相对低的case标号放在另一个switch语句中。比如,下面的
程序段把相对发生频率低的情况放在缺省的case标号内。
pMsg=ReceiveMessage();
switch (pMsg->type)
{
case FREQUENT_MSG1:
handleFrequentMsg();
break;
case FREQUENT_MSG2:
handleFrequentMsg2();
break;
......
case FREQUENT_MSGn:
handleFrequentMsgn();
break;
default: //嵌套部分用来处理不经常发生的消息
switch (pMsg->type)
{
case INFREQUENT_MSG1:
handleInfrequentMsg1();
break;
case INFREQUENT_MSG2:
handleInfrequentMsg2();
break;
......
case INFREQUENT_MSGm:
handleInfrequentMsgm();
break;
}
}
如果switch中每一种情况下都有很多的工作要做,那么把整个switch语句用一个指向函数指针的表来替换会更加有效,比如下面的
switch语句,有三种情况:
enum MsgType{Msg1, Msg2, Msg3}
switch (ReceiveMessage()
{
case Msg1;
......
case Msg2;
.....
case Msg3;
.....
}
为了提高执行速度,用下面这段代码来替换这个上面的switch语句。
/*准备工作*/
int handleMsg1(void);
int handleMsg2(void);
int handleMsg3(void);
/*创建一个函数指针数组*/
int (*MsgFunction [])()={handleMsg1, handleMsg2, handleMsg3};
/*用下面这行更有效的代码来替换switch语句*/
status=MsgFunction[ReceiveMessage()]();
10.避免使用C++的昂贵特性
C++在支持现代软件工程、OOP、结构化等方面对C进行了卓有成效的改进,但在程序代码容量、执行速度、程序复杂程度等方面比C语
言程序性能差一些。并不是所有的C++特性都是肮贵的。比如,类的定义是完全有益的。公有和私有成员数据及函数的列表与一个struct及
函数原形的列表并没有多大的差别。单纯的加入类既不会影响代码的大小,也不会影响程序的效率。但C++的多重继承、虚拟基类、模板、
异常处理及运行类型识别等特性对代码的大小和效率有负面的影响,因此对于C++的一些特性要慎重使用,可做些实验看看它们对应用程序
的影响。
4 总结语
在嵌入式实时程序设计时可以运用上面介绍的一种或多种技术来优化代码。上面介绍的方法主要是为了提高代码的效率。但是事实上,
在使用这些技术提高代码运行速度的同时会相应的产生一些负面的影响,比如增加代码的大小、降低程序可读性等。不过你可以让C/C++编
译器来进行减少代码大小的优化,而手动利用以上技术来减少代码的执行时间。在嵌入式程序设计中合理地使用这几种技术有时会达到很好
的优化效果。
1 引言
计算机技术和信息技术的高速发展的今天,计算机和计算机技术大量应用在人们的日常生活中,嵌入式计算机也得到了广泛的应用。
嵌入式计算机是指完成一种或多种特定功能的计算机系统,是软硬件的紧密结合体。具有软件代码小、高度自动化、响应速度快等特点。
特别适合于要求实时和多任务的应用体系。嵌入式实时系统是目前蓬勃发展的行业之一。
但是,实时嵌入式系统的特点使得其软件受时间和空间的严格限制,加上运行环境复杂,使得嵌入式系统软件的开发变得异常困难。
为了设计一个满足功能、性能和死线要求的系统,为了开发出安全可靠的高性能嵌入式系统,开发语言的选择十分重要。
2 嵌入式实时程序设计中语言的选择
随着嵌入式系统应用范围的不断扩大和嵌入式实时操作系统RTOS(Real Time Operating System)的广泛使用,高级语言编程已是嵌入
式系统设计的必然趋势。因为汇编语言和具体的微处理器的硬件结构密切相关,移植性较差,既不宜在复杂系统中使用,又不便于实现软
件重用;而高级语言具有良好的通用性和丰富的软件支持,便于推广、易于维护,因此高级语言编程具有许多优势。目前,在嵌入式系统
开发过程中使用的语言种类很多,但仅有少数几种语言得到了比较广泛的应用。其中C和C++是应用最广泛的。C++在支持现代软件工程、
OOP(Object Oriented Programming,面向对象的程序设计)、结构化等方面对C进行了卓有成效的改进,但在程序代码容量、执行速度、
程序复杂程度等方面比C语言程序性能差一些。由于C语言既有低级语言的直接控制硬件的能力,又有高级语言的灵活性,是目前在嵌入式
系统中应用最广泛的编程语言。随着网络技术和嵌入式技术的不断发展,Java的应用也得到广泛应用。
3 C/C++代码在实时程序设计中的优化
虽然使软件正确是一个工程合乎逻辑的最后一个步骤,但是在嵌入式的系统开发中,情况并不总是这样的。出于对低价产品的需求,
硬件的设计者需要提供刚好足够的存储器和完成工作的处理能力。所以在嵌入式软件设计的最后一个阶段则变成了对代码的优化。
现代的C和C++编译器都提供了一定程度上的代码优化。然而,大部分由编译器执行的优化仅涉及执行速度和代码大小的一个平衡。你
的程序能够变得更快或者更小,但是不可能又变快又变小。经过本人在嵌入式系统设计和实现过程中实践,下面介绍几种简单且行之有效
的C /C++代码的优化方法。
1.Inline函数
在C++中,关键字Inline可以被加入到任何函数的声明中。这个关键字请求编译器用函数内部的代码替换所有对于指出的函数的调用。
这样做在两个方面快于函数调用。这样做在两个方面快于函数调用:第一,省去了调用指令需要的执行时间;第二,省去了传递变元和传
递过程需要的时间。但是使用这种方法在优化程序速度的同时,程序长度变大了,因此需要更多的ROM。使用这种优化在Inline函数频繁调
用并且只包含几行代码的时候是最有效的。
2.用指针代替数组
在许多种情况下,可以用指针运算代替数组索引,这样做常常能产生又快又短的代码。与数组索引相比,指针一般能使代码速度更快,
占用空间更少。使用多维数组时差异更明显。下面的代码作用是相同的,但是效率不一样。
数组索引 指针运算
For(;;){ p=array
A=array[t++]; for(;;){
a=*(p++);
...... ......
} }
指针方法的优点是,array的地址每次装入地址p后,在每次循环中只需对p增量操作。在数组索引方法中,每次循环中都必须进行基于
t值求数组下标的复杂运算。
3.不定义不使用的返回值
function函数定义并不知道函数返回值是否被使用,假如返回值从来不会被用到,应该使用void来明确声明函数不返回任何值。
4.手动编写汇编
在嵌入式软件开发中,一些软件模块最好用汇编语言来写,这可以使程序更加有效。虽然C/C++编译器对代码进行了优化,但是适当的
使用内联汇编指令可以有效的提高整个系统运行的效率。
5.使用寄存器变量
在声明局部变量的时候可以使用register关键字。这就使得编译器把变量放入一个多用途的寄存器中,而不是在堆栈中,合理使用这
种方法可以提高执行速度。函数调用越是频繁,越是可能提高代码的速度。
6.使用增量和减量操作符
在使用到加一和减一操作时尽量使用增量和减量操作符,因为增量符语句比赋值语句更快,原因在于对大多数CPU来说,对内存字的增、
减量操作不必明显地使用取内存和写内存的指令,比如下面这条语句:
x=x+1;
模仿大多数微机汇编语言为例,产生的代码类似于:
move A,x ;把x从内存取出存入累加器A
add A,1 ;累加器A加1
store x ;把新值存回x
如果使用增量操作符,生成的代码如下:
incr x ;x加1
显然,不用取指令和存指令,增、减量操作执行的速度加快,同时长度也缩短了。
7.减少函数调用参数
使用全局变量比函数传递参数更加有效率。这样做去除了函数调用参数入栈和函数完成后参数出栈所需要的时间。然而决定使用全局
变量会影响程序的模块化和重入,故要慎重使用。
8.Switch语句中根据发生频率来进行case排序
switch语句是一个普通的编程技术,编译器会产生if-else-if的嵌套代码,并按照顺序进行比较,发现匹配时,就跳转到满足条件的
语句执行。使用时需要注意。每一个由机器语言实现的测试和跳转仅仅是为了决定下一步要做什么,就把宝贵的处理器时间耗尽。为了提
高速度,没法把具体的情况按照它们发生的相对频率排序。换句话说,把最可能发生的情况放在第一位,最不可能的情况放在最后。
9.将大的switch语句转为嵌套switch语句
当switch语句中的case标号很多时,为了减少比较的次数,明智的做法是把大switch语句转为嵌套switch语句。把发生频率高的case
标号放在一个switch语句中,并且是嵌套switch语句的最外层,发生相对频率相对低的case标号放在另一个switch语句中。比如,下面的
程序段把相对发生频率低的情况放在缺省的case标号内。
pMsg=ReceiveMessage();
switch (pMsg->type)
{
case FREQUENT_MSG1:
handleFrequentMsg();
break;
case FREQUENT_MSG2:
handleFrequentMsg2();
break;
......
case FREQUENT_MSGn:
handleFrequentMsgn();
break;
default: //嵌套部分用来处理不经常发生的消息
switch (pMsg->type)
{
case INFREQUENT_MSG1:
handleInfrequentMsg1();
break;
case INFREQUENT_MSG2:
handleInfrequentMsg2();
break;
......
case INFREQUENT_MSGm:
handleInfrequentMsgm();
break;
}
}
如果switch中每一种情况下都有很多的工作要做,那么把整个switch语句用一个指向函数指针的表来替换会更加有效,比如下面的
switch语句,有三种情况:
enum MsgType{Msg1, Msg2, Msg3}
switch (ReceiveMessage()
{
case Msg1;
......
case Msg2;
.....
case Msg3;
.....
}
为了提高执行速度,用下面这段代码来替换这个上面的switch语句。
/*准备工作*/
int handleMsg1(void);
int handleMsg2(void);
int handleMsg3(void);
/*创建一个函数指针数组*/
int (*MsgFunction [])()={handleMsg1, handleMsg2, handleMsg3};
/*用下面这行更有效的代码来替换switch语句*/
status=MsgFunction[ReceiveMessage()]();
10.避免使用C++的昂贵特性
C++在支持现代软件工程、OOP、结构化等方面对C进行了卓有成效的改进,但在程序代码容量、执行速度、程序复杂程度等方面比C语
言程序性能差一些。并不是所有的C++特性都是肮贵的。比如,类的定义是完全有益的。公有和私有成员数据及函数的列表与一个struct及
函数原形的列表并没有多大的差别。单纯的加入类既不会影响代码的大小,也不会影响程序的效率。但C++的多重继承、虚拟基类、模板、
异常处理及运行类型识别等特性对代码的大小和效率有负面的影响,因此对于C++的一些特性要慎重使用,可做些实验看看它们对应用程序
的影响。
4 总结语
在嵌入式实时程序设计时可以运用上面介绍的一种或多种技术来优化代码。上面介绍的方法主要是为了提高代码的效率。但是事实上,
在使用这些技术提高代码运行速度的同时会相应的产生一些负面的影响,比如增加代码的大小、降低程序可读性等。不过你可以让C/C++编
译器来进行减少代码大小的优化,而手动利用以上技术来减少代码的执行时间。在嵌入式程序设计中合理地使用这几种技术有时会达到很好
的优化效果。
#12
其实我也没有好好去看这些 “C++的昂贵特性”编译以后的代码?也没去做过效率测试!
我现在就是作ARM下面的旅馆管理系统!呵呵,好像硬件环境比较充裕哦!32M内存,64MFLASH
(还没确定),别人给我说内存大着呢!你尽管浪费好啦!只要快点给我完成!哀!没办法,我就只用了一大队数组完成了基本数据存储!
本来想用STL,但我还不熟悉,呵呵,没办法,只好自己写了简单的list来实现,不过心里总不踏实!!!
我现在就是作ARM下面的旅馆管理系统!呵呵,好像硬件环境比较充裕哦!32M内存,64MFLASH
(还没确定),别人给我说内存大着呢!你尽管浪费好啦!只要快点给我完成!哀!没办法,我就只用了一大队数组完成了基本数据存储!
本来想用STL,但我还不熟悉,呵呵,没办法,只好自己写了简单的list来实现,不过心里总不踏实!!!
#13
To:wwwer
ARM下面支持C++的环境有那些?
ARM下面支持C++的环境有那些?
#14
ARM公司自己出的ADS就支持C++
#15
还有一个什么EC++标准,我怀疑这是谁搞出来的?
#16
写得蛮好,赶快去改原来写过的代码,呵呵。