1.TTL电平:
输出高电平>2.4V,输出低电平 <0.4V。
在室温下,一般输出高电平是3.5V,输出低电平是0.2V。
最小输入高电平和低电平:输入高电平>=2.0V,输入低电平 <=0.8V,噪声容限是0.4V。
2.CMOS电平:
1逻辑电平电压接近于电源电压,0逻辑电平接近于0V。而且具有很宽的噪声容。
3.rs232电平:
-5v~15v为逻辑电平1,+5~+15符为逻辑电平0.
输出高电平>2.4V,输出低电平 <0.4V。
在室温下,一般输出高电平是3.5V,输出低电平是0.2V。
最小输入高电平和低电平:输入高电平>=2.0V,输入低电平 <=0.8V,噪声容限是0.4V。
2.CMOS电平:
1逻辑电平电压接近于电源电压,0逻辑电平接近于0V。而且具有很宽的噪声容。
3.rs232电平:
-5v~15v为逻辑电平1,+5~+15符为逻辑电平0.
什么是前端总线?不是超频的方法之一,也不是用来超频的。
我们知道,电脑有许多配件,配件不同,速度也就不同。在286、386和早期的486 电脑里,CPU的速度不是太高,和内存保持一样的速度。后来随着CPU速度的飞速提升,内存由于电气结构关系,无法象CPU那样提升很高的速度(就算现在内存达到400、533,但跟CPU的几个G的速度相比,根本就不是一个级别的),于是造成了内存和CPU之间出现了速度差异,这时就提出一个CPU的主频、倍频和外频的概念,外频顾名思义就是CPU外部的频率,也就是内存的频率,CPU以这个频率来与内存联系。CPU的主频就是CPU内部的实际运算速度,主频肯定是比外频高的,高一定的倍数,这个数就是倍频。举个例子,你从电脑垃圾堆里拣到一个被抛弃的INTEL 486 CPU,上面印着486 DX/2 66。这个486的CPU的主频是66MHZ,DX/2代表是2倍频的,于是算出CPU的外频是33MZ,也就是内存的工作频率,这同时也是前端总线 FSB的频率。因为CPU是通过前端总线来与内存发生联系的,所以内存的工作频率(或者说外频也行)就是前端总线的频率。刚才这个垃圾堆里的486 CPU,前端总线的频率就是33MZ。这样的前端总线结构一直延续到486之后的奔腾(俗话说的586)、奔腾2、奔腾3,例如一颗奔3 933MHZ的CPU,外频133,也就是说它的前端总线是133MHZ,内存工作频率也是133。阅读全文
我们知道,电脑有许多配件,配件不同,速度也就不同。在286、386和早期的486 电脑里,CPU的速度不是太高,和内存保持一样的速度。后来随着CPU速度的飞速提升,内存由于电气结构关系,无法象CPU那样提升很高的速度(就算现在内存达到400、533,但跟CPU的几个G的速度相比,根本就不是一个级别的),于是造成了内存和CPU之间出现了速度差异,这时就提出一个CPU的主频、倍频和外频的概念,外频顾名思义就是CPU外部的频率,也就是内存的频率,CPU以这个频率来与内存联系。CPU的主频就是CPU内部的实际运算速度,主频肯定是比外频高的,高一定的倍数,这个数就是倍频。举个例子,你从电脑垃圾堆里拣到一个被抛弃的INTEL 486 CPU,上面印着486 DX/2 66。这个486的CPU的主频是66MHZ,DX/2代表是2倍频的,于是算出CPU的外频是33MZ,也就是内存的工作频率,这同时也是前端总线 FSB的频率。因为CPU是通过前端总线来与内存发生联系的,所以内存的工作频率(或者说外频也行)就是前端总线的频率。刚才这个垃圾堆里的486 CPU,前端总线的频率就是33MZ。这样的前端总线结构一直延续到486之后的奔腾(俗话说的586)、奔腾2、奔腾3,例如一颗奔3 933MHZ的CPU,外频133,也就是说它的前端总线是133MHZ,内存工作频率也是133。阅读全文
一、RS-232-C
RS-232C标准(协议)的全称是EIA-RS-232C标准,其中EIA(Electronic Industry Association)代表美国电子工业协会,RS(recommeded standard)代表推荐标准,232是标识号,C代表RS232的最新一次修改(1969),在这之前,有RS232B、RS232A。。它规定连接电缆和机械、电气特性、信号功能及传送过程。常用物理标准还有有EIARS-232-C、EIARS-422-A、 EIARS-423A、EIARS-485。这里只介绍EIARS-232-C(简称232,RS232)。 例如,目前在IBM PC机上的COM1、COM2接口,就是RS-232C接口。阅读全文
RS-232C标准(协议)的全称是EIA-RS-232C标准,其中EIA(Electronic Industry Association)代表美国电子工业协会,RS(recommeded standard)代表推荐标准,232是标识号,C代表RS232的最新一次修改(1969),在这之前,有RS232B、RS232A。。它规定连接电缆和机械、电气特性、信号功能及传送过程。常用物理标准还有有EIARS-232-C、EIARS-422-A、 EIARS-423A、EIARS-485。这里只介绍EIARS-232-C(简称232,RS232)。 例如,目前在IBM PC机上的COM1、COM2接口,就是RS-232C接口。阅读全文
预处理程序提供了条件编译的功能。 可以按不同的条件去编译不同的程序部分,因而产生不同的目标代码文件。 这对于程序的移植和调试是很有用的。
条件编译有三种形式,下面分别介绍:
1. 第一种形式:
#ifdef 标识符
程序段1
#else
程序段2
#endif
它的功能是,如果标识符已被 #define命令定义过则对程序段1进行编译;否则对程序段2进行编译。
如果没有程序段2(它为空),本格式中的#else可以没有, 即可以写为:阅读全文
条件编译有三种形式,下面分别介绍:
1. 第一种形式:
#ifdef 标识符
程序段1
#else
程序段2
#endif
它的功能是,如果标识符已被 #define命令定义过则对程序段1进行编译;否则对程序段2进行编译。
如果没有程序段2(它为空),本格式中的#else可以没有, 即可以写为:阅读全文
1.求下面函数的返回值(微软)
int func(x)
{
int countx = 0;
while(x)
{
countx ++;
x = x&(x-1);
}
return countx;
}
假定x = 9999。 答案:8阅读全文
int func(x)
{
int countx = 0;
while(x)
{
countx ++;
x = x&(x-1);
}
return countx;
}
假定x = 9999。 答案:8阅读全文
Embedded Software Design Engineer
1 读程序段,回答问题
int main(int argc,char *argv[])
{
int c=9,d=0;
c=c++%5;
d=c;
printf("d=%d\n",d);
return 0;
}
a) 写出程序输出
b) 在一个可移植的系统中这种表达式是否存在风险?why?阅读全文
1 读程序段,回答问题
int main(int argc,char *argv[])
{
int c=9,d=0;
c=c++%5;
d=c;
printf("d=%d\n",d);
return 0;
}
a) 写出程序输出
b) 在一个可移植的系统中这种表达式是否存在风险?why?阅读全文
◆假定在所有的程序中必须的头文件都已经被正确包含。
考虑如下的数据类型:
◆char为1个字节
◆int为4个字节
◆long int为4个字节
◆float为4个字节
◆double为个8字节
◆long double为8个字节
◆指针为4个字节阅读全文
考虑如下的数据类型:
◆char为1个字节
◆int为4个字节
◆long int为4个字节
◆float为4个字节
◆double为个8字节
◆long double为8个字节
◆指针为4个字节阅读全文
五大内存分区
在C++中,内存分成5个区,他们分别是堆、栈、自由存储区、全局/静态存储区和常量存储区。
栈,就是那些由编译器在需要的时候分配,在不需要的时候自动清楚的变量的存储区。里面的变量通常是局部变量、函数参数等。
堆,就是那些由new分配的内存块,他们的释放编译器不去管,由我们的应用程序去控制,一般一个new就要对应一个delete。如果程序员没有释放掉,那么在程序结束后,操作系统会自动回收。
自由存储区,就是那些由malloc等分配的内存块,他和堆是十分相似的,不过它是用free来结束自己的生命的。
全局/静态存储区,全局变量和静态变量被分配到同一块内存中,在以前的C语言中,全局变量又分为初始化的和未初始化的,在C++里面没有这个区分了,他们共同占用同一块内存区。
常量存储区,这是一块比较特殊的存储区,他们里面存放的是常量,不允许修改(当然,你要通过非正当手段也可以修改,而且方法很多)
明确区分堆与栈阅读全文
在C++中,内存分成5个区,他们分别是堆、栈、自由存储区、全局/静态存储区和常量存储区。
栈,就是那些由编译器在需要的时候分配,在不需要的时候自动清楚的变量的存储区。里面的变量通常是局部变量、函数参数等。
堆,就是那些由new分配的内存块,他们的释放编译器不去管,由我们的应用程序去控制,一般一个new就要对应一个delete。如果程序员没有释放掉,那么在程序结束后,操作系统会自动回收。
自由存储区,就是那些由malloc等分配的内存块,他和堆是十分相似的,不过它是用free来结束自己的生命的。
全局/静态存储区,全局变量和静态变量被分配到同一块内存中,在以前的C语言中,全局变量又分为初始化的和未初始化的,在C++里面没有这个区分了,他们共同占用同一块内存区。
常量存储区,这是一块比较特殊的存储区,他们里面存放的是常量,不允许修改(当然,你要通过非正当手段也可以修改,而且方法很多)
明确区分堆与栈阅读全文
C中CONST的使用:
const是一个C语言的关键字,它限定一个变量不允许被改变。使用const在一定程度上可以提
高程序的健壮性,另外,在观看别人代码的时候,清晰理解const所起的作用,对理解对方的
程序也有一些帮助。
虽然这听起来很简单,但实际上,const的使用也是c语言中一个比较微妙的地方,微妙在
何处呢?请看下面几个问题。阅读全文
const是一个C语言的关键字,它限定一个变量不允许被改变。使用const在一定程度上可以提
高程序的健壮性,另外,在观看别人代码的时候,清晰理解const所起的作用,对理解对方的
程序也有一些帮助。
虽然这听起来很简单,但实际上,const的使用也是c语言中一个比较微妙的地方,微妙在
何处呢?请看下面几个问题。阅读全文
一、 static 变量
static变量大致分为三种用法
1. 用于局部变量中,成为静态局部变量. 静态局部变量有两个用法,记忆功能和全局生存期.
2. 用于全局变量,主要作用是限制此全局变量被其他的文件调用.
3. 用于类中的成员.表示这个成员是属于这个类但是不属于类中任意特定对象阅读全文
static变量大致分为三种用法
1. 用于局部变量中,成为静态局部变量. 静态局部变量有两个用法,记忆功能和全局生存期.
2. 用于全局变量,主要作用是限制此全局变量被其他的文件调用.
3. 用于类中的成员.表示这个成员是属于这个类但是不属于类中任意特定对象阅读全文
a) 一个整型数(An integer)
b)一个指向整型数的指针( A pointer to an integer)
c)一个指向指针的的指针,它指向的指针是指向一个整型数( A pointer to a pointer to an intege)r
d)一个有10个整型数的数组( An array of 10 integers)
e) 一个有10个指针的数组,该指针是指向一个整型数的。(An array of 10 pointers to integers)
f) 一个指向有10个整型数数组的指针( A pointer to an array of 10 integers)
g) 一个指向函数的指针,该函数有一个整型参数并返回一个整型数(A pointer to a function that takes an integer as an argument and returns an integer)
h) 一个有10个指针的数组,该指针指向一个函数,该函数有一个整型参数并返回一个整型数( An array of ten pointers to functions that take an integer argument and return an integer )
答案是:
a) int a; // An integer
b) int *a; // A pointer to an integer
c) int **a; // A pointer to a pointer to an integer
d) int a[10]; // An array of 10 integers
e) int *a[10]; // An array of 10 pointers to integers
f) int (*a)[10]; // A pointer to an array of 10 integers
g) int (*a)(int); // A pointer to a function a that takes an integer argument and returns an integer
h) int (*a[10])(int); // An array of 10 pointers to functions that take an integer argument and return an integer
如何区分:
在没括号的定义中我们以*为分界如(int */a[10])首先看右边我们确定它是一个数组,再看左边确定它的数组内容是一个指针并且指针指向整型数;
在有括号的定义中我们就把有括号中有指针的都删掉如
(int (*a)[10]=`=int () [10])由删掉的内容我们首先确定它是一个指针,再通过删掉后剩下的内容我们确定了这个指针指向了一个有10整型数的数组;
对于函数指针也一样;
b)一个指向整型数的指针( A pointer to an integer)
c)一个指向指针的的指针,它指向的指针是指向一个整型数( A pointer to a pointer to an intege)r
d)一个有10个整型数的数组( An array of 10 integers)
e) 一个有10个指针的数组,该指针是指向一个整型数的。(An array of 10 pointers to integers)
f) 一个指向有10个整型数数组的指针( A pointer to an array of 10 integers)
g) 一个指向函数的指针,该函数有一个整型参数并返回一个整型数(A pointer to a function that takes an integer as an argument and returns an integer)
h) 一个有10个指针的数组,该指针指向一个函数,该函数有一个整型参数并返回一个整型数( An array of ten pointers to functions that take an integer argument and return an integer )
答案是:
a) int a; // An integer
b) int *a; // A pointer to an integer
c) int **a; // A pointer to a pointer to an integer
d) int a[10]; // An array of 10 integers
e) int *a[10]; // An array of 10 pointers to integers
f) int (*a)[10]; // A pointer to an array of 10 integers
g) int (*a)(int); // A pointer to a function a that takes an integer argument and returns an integer
h) int (*a[10])(int); // An array of 10 pointers to functions that take an integer argument and return an integer
如何区分:
在没括号的定义中我们以*为分界如(int */a[10])首先看右边我们确定它是一个数组,再看左边确定它的数组内容是一个指针并且指针指向整型数;
在有括号的定义中我们就把有括号中有指针的都删掉如
(int (*a)[10]=`=int () [10])由删掉的内容我们首先确定它是一个指针,再通过删掉后剩下的内容我们确定了这个指针指向了一个有10整型数的数组;
对于函数指针也一样;
在C语言的应用领域,如通讯领域和嵌入式系统领域,一个的软件项目通常包含很多复杂的功能,实现这个项目不是一个程序员单枪匹马可以胜任的,往往需要一个团队的有效合作,另外,在一个以C代码为主的完整的项目中,经常也需要加入一些其他语言的代码,例如,C代码和汇编代码的混合使用,C文件和C++的同时使用。这些都增加了一个软件项目的复杂程度,为了提高软件质量,合理组织的各种代码和文件是非常重要的。 阅读全文
最近需要在pxa270的嵌入式平台上应用数据库进行通信信息管理,客户要求使用mysql数据库,接下任务后,在网上一查才知道mysql 根本很少用于嵌入式环境,而且支持的少数几种芯片中并没有arm的分发包!继续搜索有没有mysql在arm平台移植的相关文章,几乎找不到相关资料.而自己在网上发了一些帖却没有收到一个回复,没办法,只能硬着头皮自己动手了.幸好经过一番”苦战”,今天终于克服了所有障碍,让mysql在270板子上跑了起来!而且简单的测试也都收到了预期的效果,不过还要看客户的经一步测试了.
现在将mysql 的arm+linux移植经验贴出来,希望对以后做相关方面工作的人有所帮助.
首先是要从网上获取mysql的源码包,官方网址如下:
http://ftp.plusline.de/mysql/Downloads/
我用的是mysql-5.0.22.tar.gz
采用的交叉编译器是适合于270板子的codesourcery这要根据具体的情况来进行修改.阅读全文
现在将mysql 的arm+linux移植经验贴出来,希望对以后做相关方面工作的人有所帮助.
首先是要从网上获取mysql的源码包,官方网址如下:
http://ftp.plusline.de/mysql/Downloads/
我用的是mysql-5.0.22.tar.gz
采用的交叉编译器是适合于270板子的codesourcery这要根据具体的情况来进行修改.阅读全文
1.5 写个C语言程序调用SQLite
现在我们来写个C/C++程序,调用 sqlite 的 API 接口函数。
下面是一个C程序的例子,显示怎么使用 sqlite 的 C/C++ 接口. 数据库的名字由第一个参数取得且第二个参数或更多的参数是 SQL 执行语句. 这个函数调用sqlite3_open() 在 22 行打开数据库, sqlite3_exec() 在 27 行执行 SQL 命令, 并且sqlite3_close() 在 31 行关闭数据库连接。
代码:
// name: opendbsqlite.c
// This file is used to test C/C++ API for sqlite
// Author : zieckey
// 2006/04/11
#include
#include
int main( void )
{
sqlite3 *db=NULL;
char *zErrMsg = 0;
int rc;
rc = sqlite3_open("zieckey.db", &db); //打开指定的数据库文件,如果不存在将创建一个同名的数据库文件
if( rc ){
fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
sqlite3_close(db);
exit(1);
}
else printf("open zieckey.db successfully!\n");
sqlite3_close(db); //关闭数据库
return 0;
}
编译:# gcc opendbsqlite.c -o db.out
也许会碰到类似这样的问题:
/tmp/ccTkItnN.o(.text+0x2b): In function `main':
: undefined reference to `sqlite3_open'
/tmp/ccTkItnN.o(.text+0x45): In function `main':
: undefined reference to `sqlite3_errmsg'
/tmp/ccTkItnN.o(.text+0x67): In function `main':
: undefined reference to `sqlite3_close'
/tmp/ccTkItnN.o(.text+0x8f): In function `main':
: undefined reference to `sqlite3_close'
collect2: ld returned 1 exit status
这是个没有找到库文件的问题。
由于用到了用户自己的库文件,所用应该指明所用到的库,我们可以这样编译:
# gcc opendbsqlite.c -o db.out -lsqlite3
我用用 -lsqlite3 选项就可以了(前面我们生成的库文件是 libsqlite3.so.0.8.6 等,
去掉前面的lib和后面的版本标志,就剩下 sqlite3 了所以是 -lsqlite3 )。
如果我们在编译安装的时候,选择了安装路径,例如这样的话:
.......
# ../sqlite/configure --prefix=/usr/local/arm-linux/sqlite-ix86-linux
.......
这样编译安装时,sqlite的库文件将会生成在 /usr/local/arm-linux/sqlite-ix86-linux/lib 目录下
这时编译还要指定库文件路径,因为系统默认的路径没有包含 /usr/local/arm-linux/sqlite-ix86-linux/lib
# gcc opendbsqlite.c -lsqlite3 -L/usr/local/arm-linux/sqlite-ix86-linux/lib
如果还不行的话,可能还需要指定头文件 sqlite3.h 的路径,如下:
# gcc opendbsqlite.c -lsqlite3 -L/usr/local/arm-linux/sqlite-ix86-linux/lib -I/usr/local/arm-linux/sqlite-ix86-linux/include
这样编译应该就可以了 ,运行:
# ./db.out
open zieckey.db successfully!
是不是很有成就感阿 ,呵呵,这个上手还是很快的。
现在我们来写个C/C++程序,调用 sqlite 的 API 接口函数。
下面是一个C程序的例子,显示怎么使用 sqlite 的 C/C++ 接口. 数据库的名字由第一个参数取得且第二个参数或更多的参数是 SQL 执行语句. 这个函数调用sqlite3_open() 在 22 行打开数据库, sqlite3_exec() 在 27 行执行 SQL 命令, 并且sqlite3_close() 在 31 行关闭数据库连接。
代码:
// name: opendbsqlite.c
// This file is used to test C/C++ API for sqlite
// Author : zieckey
// 2006/04/11
#include
#include
int main( void )
{
sqlite3 *db=NULL;
char *zErrMsg = 0;
int rc;
rc = sqlite3_open("zieckey.db", &db); //打开指定的数据库文件,如果不存在将创建一个同名的数据库文件
if( rc ){
fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
sqlite3_close(db);
exit(1);
}
else printf("open zieckey.db successfully!\n");
sqlite3_close(db); //关闭数据库
return 0;
}
编译:# gcc opendbsqlite.c -o db.out
也许会碰到类似这样的问题:
/tmp/ccTkItnN.o(.text+0x2b): In function `main':
: undefined reference to `sqlite3_open'
/tmp/ccTkItnN.o(.text+0x45): In function `main':
: undefined reference to `sqlite3_errmsg'
/tmp/ccTkItnN.o(.text+0x67): In function `main':
: undefined reference to `sqlite3_close'
/tmp/ccTkItnN.o(.text+0x8f): In function `main':
: undefined reference to `sqlite3_close'
collect2: ld returned 1 exit status
这是个没有找到库文件的问题。
由于用到了用户自己的库文件,所用应该指明所用到的库,我们可以这样编译:
# gcc opendbsqlite.c -o db.out -lsqlite3
我用用 -lsqlite3 选项就可以了(前面我们生成的库文件是 libsqlite3.so.0.8.6 等,
去掉前面的lib和后面的版本标志,就剩下 sqlite3 了所以是 -lsqlite3 )。
如果我们在编译安装的时候,选择了安装路径,例如这样的话:
.......
# ../sqlite/configure --prefix=/usr/local/arm-linux/sqlite-ix86-linux
.......
这样编译安装时,sqlite的库文件将会生成在 /usr/local/arm-linux/sqlite-ix86-linux/lib 目录下
这时编译还要指定库文件路径,因为系统默认的路径没有包含 /usr/local/arm-linux/sqlite-ix86-linux/lib
# gcc opendbsqlite.c -lsqlite3 -L/usr/local/arm-linux/sqlite-ix86-linux/lib
如果还不行的话,可能还需要指定头文件 sqlite3.h 的路径,如下:
# gcc opendbsqlite.c -lsqlite3 -L/usr/local/arm-linux/sqlite-ix86-linux/lib -I/usr/local/arm-linux/sqlite-ix86-linux/include
这样编译应该就可以了 ,运行:
# ./db.out
open zieckey.db successfully!
是不是很有成就感阿 ,呵呵,这个上手还是很快的。
linux下遍历查找指定文件夹下的文件名,find+grep配合查找包含某字符串的文件并显示行号。
Unix/LinuxC技术 jackxiang 2008-12-4 15:36
1)linux下查找指定文件名:
find PATH -type f -name "aaa.txt"
2)find+grep配合查找包含某字符串的文件并显示行号:
#> find . -type f -exec grep 'mingtian' -l {} \;
grep -l :是显示匹配的内容的文件名字!
或者:
#> find . -type f -name "*.*" |xargs grep 'xiaoshou' -l
(这个方法 不好,挺乱的,还慢,推荐前一个方法!)
such as :
find . -type f -name "*.php"|xargs grep -in "date" -R
find PATH -type f -name "aaa.txt"
2)find+grep配合查找包含某字符串的文件并显示行号:
#> find . -type f -exec grep 'mingtian' -l {} \;
grep -l :是显示匹配的内容的文件名字!
或者:
#> find . -type f -name "*.*" |xargs grep 'xiaoshou' -l
(这个方法 不好,挺乱的,还慢,推荐前一个方法!)
such as :
find . -type f -name "*.php"|xargs grep -in "date" -R
linux下文件的类型是不依赖于其后缀名的,但一般来讲:
.o,是目标文件,相当于windows中的.obj文件
.so 为共享库,是shared object,用于动态连接的,和dll差不多
.a为静态库,是好多个.o合在一起,用于静态连接
.la为libtool自动生成的一些共享库,vi编辑查看,主要记录了一些配置信息。可以用如下命令查看*.la文件的格式 $file *.la
*.la: ASCII English text
所以可以用vi来查看其内容。
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@阅读全文
.o,是目标文件,相当于windows中的.obj文件
.so 为共享库,是shared object,用于动态连接的,和dll差不多
.a为静态库,是好多个.o合在一起,用于静态连接
.la为libtool自动生成的一些共享库,vi编辑查看,主要记录了一些配置信息。可以用如下命令查看*.la文件的格式 $file *.la
*.la: ASCII English text
所以可以用vi来查看其内容。
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@阅读全文
1.数组a[N],存放了1至N-1范围内N个数,其中某个数重复一次。写一个函数,找出被重复的数字.时间复杂度必须为o(N)函数原型:
int do_dup(int a[],int N)
算法:
a1+a2+ ......+aN=1+2+3+..+x+..+(N-1)+(N-x);
s1=a1+a2+....+aN;
s2=1+2+3+...+N;
x=s1-s2+N;
#####################################################阅读全文
int do_dup(int a[],int N)
算法:
a1+a2+ ......+aN=1+2+3+..+x+..+(N-1)+(N-x);
s1=a1+a2+....+aN;
s2=1+2+3+...+N;
x=s1-s2+N;
#####################################################阅读全文