2021-3-22 997 0
编程语言

本文代码托管于githubcmake_democmake中一些预定义变量PROJECT_SOURCE_DIR工程的根目录PROJECT_BINARY_DIR运行cmake命令的目录,通常是${PROJECT_SOURCE_DIR}/buildCMAKE_INCLUDE_PATH环境变量,非cmake变量CMAKE_LIBRARY_PATH环境变量CMAKE_CURRENT_SOURCE_DIR当前处理的CMakeLists.txt所在的路径CMAKE_CURRENT_BINARY_DIRtarget编译目录使用ADD_SURDIRECTORY(srcbin)可以更改此变量的值SET(EXECUTABLE_OUTPUT_PATH<新路径>)并不会对此变量有影响,只是改变了最终目标文件的存储路径CMAKE_CURRENT_LIST_FILE输出调用这个变量的CMakeLists.txt的完整路径CMAKE_CURRENT_LIST_LINE输出这个变量所在的行CMAKE_MODULE_PATH定义自己的cmake模块所在的路径SET(CMAKE_MODULE_PATH${PROJECT_SOURCE_DIR}/cmake),然后可以用INCLUDE命令来调用自己的模块EXECUTABLE_OUTPUT_PATH重新定义目标二进制可执行文件的存放位置LIBRARY_OUTPUT_PATH重新定义目标链接库文件的存放位置PROJECT_NAME返回通过PROJECT指令定义的项目名称CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS用来控制IFELSE语句的书写方式系统信息CMAKE_MAJOR_VERSIONcmake主版本号,如2.8.6中的2CMAKE_MINOR_VERSIONcmake次版本号,如2.8.6中的8CMAKE_PATCH_VERSIONcmake补丁等级,如2.8.6中的6CMAKE_SYSTEM系统名称,例如Linux-2.6.22CAMKE_SYSTEM_NAME不包含版本的系统名,如LinuxCMAKE_SYSTEM_VERSION系统版本,如2.6.22CMAKE_SYSTEM_PROCESSOR处理器名称,如i686UNIX在所有的类UNIX平台为TRUE,包括OSX和cygwinWIN32在所有的win32平台为TRUE,包括cygwin开关选项BUILD_SHARED_LIBS控制默认的库编译方式。如果未进行设置,使用ADD_LIBRARY时又没有指定库类型,默认编译生成的库都是静态库(可在t3中稍加修改进行验证)CMAKE_C_FLAGS设置C编译选项CMAKE_CXX_FLAGS设置C++编译选项cmake常用命令基本语法规则:cmake变量使用${}方式取值,但是在IF控制语句中是直接使用变量名环境变量使用$ENV{}方式取值,使用SET(ENV{VAR}VALUE)赋值指令(参数1参数2…)参数使用括弧括起,参数之间使用空格或分号分开。以ADD_EXECUTABLE指令为例:ADD_EXECUTABLE(hellomain.cfunc.c)或者ADD_EXECUTABLE(hellomain.c;func.c)指令是大小写无关的,参数和变量是大小写相关的。推荐你全部使用大写指令。部分常用命令列表:PROJECTPROJECT(projectname[CXX][C][Java])指定工程名称,并可指定工程支持的语言。支持语言列表可忽略,默认支持所有语言SETSET(VAR[VALUE][CACHETYPEDOCSTRING[FORCE]])定义变量(可以定义多个VALUE,如SET(SRC_LISTmain.cutil.creactor.c))MESSAGEMESSAGE([SEND_ERROR|STATUS|FATAL_ERROR]“messagetodisplay”…)向终端输出用户定义的信息或变量的值SEND_ERROR,产生错误,生成过程被跳过STATUS,输出前缀为—的信息FATAL_ERROR,立即终止所有cmake过程ADD_EXECUTABLEADD_EXECUTABLE(bin_file_name${SRC_LIST})生成可执行文件ADD_LIBRARYADD_LIBRARY(libname[SHARED|STATIC|MODULE][EXCLUDE_FROM_ALL]SRC_LIST)生成动态库或静态库SHARED动态库STATIC静态库MODULE在使用dyld的系统有效,若不支持dyld,等同于SHAREDEXCLUDE_FROM_ALL表示该库不会被默认构建SET_TARGET_PROPERTIES设置输出的名称,设置动态库的版本和API版本CMAKE_MINIMUM_REQUIREDCMAKE_MINIMUM_REQUIRED(VERSIONversion_number[FATAL_ERROR])声明CMake的版本要求ADD_SUBDIRECTORYADD_SUBDIRECTORY(src_dir[binary_dir][EXCLUDE_FROM_ALL])向当前工程添加存放源文件的子目录,并可以指定中间二进制和目标二进制的存放位置EXCLUDE_FROM_ALL含义:将这个目录从编译过程中排除SUBDIRSdeprecated,不再推荐使用(hellosample)相当于分别写ADD_SUBDIRECTORY(hello),ADD_SUBDIRECTORY(sample)INCLUDE_DIRECTORIESINCLUDE_DIRECTORIES([AFTER|BEFORE][SYSTEM]dir1dir2…)向工程添加多个特定的头文件搜索路径,路径之间用空格分隔,如果路径包含空格,可以使用双引号将它括起来,默认的行为为追加到当前头文件搜索路径的后面。有如下两种方式可以控制搜索路径添加的位置:CMAKE_INCLUDE_DIRECTORIES_BEFORE,通过SET这个cmake变量为on,可以将添加的头文件搜索路径放在已有路径的前面通过AFTER或BEFORE参数,也可以控制是追加还是置前LINK_DIRECTORIESLINK_DIRECTORIES(dir1dir2…)添加非标准的共享库搜索路径TARGET_LINK_LIBRARIESTARGET_LINK_LIBRARIES(targetlib1lib2…)为target添加需要链接的共享库ADD_DEFINITIONS向C/C++编译器添加-D定义ADD_DEFINITIONS(-DENABLE_DEBUG-DABC),参数之间用空格分隔ADD_DEPENDENCIESADD_DEPENDENCIES(target-namedepend-target1depend-target2…)定义target依赖的其他target,确保target在构建之前,其依赖的target已经构建完毕AUX_SOURCE_DIRECTORYAUX_SOURCE_DIRECTORY(dirVAR)发现一个目录下所有的源代码文件并将列表存储在一个变量中把当前目录下的所有源码文件名赋给变量DIR_HELLO_SRCSEXEC_PROGRAMEXEC_PROGRAM(Executable[dirwheretorun][ARGS<args>][OUTPUT_VARIABLE<var>][RETURN_VALUE<value>])用于在指定目录运行某个程序(默认为当前CMakeLists.txt所在目录),通过ARGS添加参数,通过OUTPUT_VARIABLE和RETURN_VALUE获取输出和返回值,如下示例#在src中运行ls命令,在src/CMakeLists.txt添加EXEC_PROGRAM(lsARGS"*.c"OUTPUT_VARIABLELS_OUTPUTRETURN_VALUELS_RVALUE)IF(notLS_RVALUE)MESSAGE(STATUS"lsresult:"${LS_OUTPUT})#缩进仅为美观,语法无要求ENDIF(notLS_RVALUE)INCLUDEINCLUDE(file[OPTIONAL])用来载入CMakeLists.txt文件INCLUDE(module[OPTIONAL])用来载入预定义的cmake模块OPTIONAL参数的左右是文件不存在也不会产生错误可以载入一个文件,也可以载入预定义模块(模块会在CMAKE_MODULE_PATH指定的路径进行搜索)载入的内容将在处理到INCLUDE语句时直接执行FIND_FIND_FILE(<VAR>namepath1path2…)VAR变量代表找到的文件全路径,包含文件名FIND_LIBRARY(<VAR>namepath1path2…)VAR变量代表找到的库全路径,包含库文件名FIND_LIBRARY(libXX11/usr/lib)IF(NOTlibx)MESSAGE(FATAL_ERROR"libXnotfound")ENDIF(NOTlibX)FIND_PATH(<VAR>namepath1path2…)VAR变量代表包含这个文件的路径FIND_PROGRAM(<VAR>namepath1path2…)VAR变量代表包含这个程序的全路径FIND_PACKAGE(<name>[major.minor][QUIET][NO_MODULE][[REQUIRED|COMPONENTS][componets…]])用来调用预定义在CMAKE_MODULE_PATH下的Find<name>.cmake模块,你也可以自己定义Find<name>模块,通过SET(CMAKE_MODULE_PATHdir)将其放入工程的某个目录供工程使用IF语法:IF(expression)COMMAND1(ARGS...)COMMAND2(ARGS...)...ELSE(expression)COMMAND1(ARGS...)COMMAND2(ARGS...)...ENDIF(expression)#一定要有ENDIF与IF对应IF(expression),expression不为:空,0,N,NO,OFF,FALSE,NOTFOUND或<var>_NOTFOUND,为真IF(notexp),与上面相反IF(var1ANDvar2)IF(var1ORvar2)IF(COMMANDcmd)如果cmd确实是命令并可调用,为真IF(EXISTSdir)IF(EXISTSfile)如果目录或文件存在,为真IF(file1IS_NEWER_THANfile2),当file1比file2新,或file1/file2中有一个不存在时为真,文件名需使用全路径IF(IS_DIRECTORYdir)当dir是目录时,为真IF(DEFINEDvar)如果变量被定义,为真IF(varMATCHESregex)此处var可以用var名,也可以用${var}IF(stringMATCHESregex)当给定的变量或者字符串能够匹配正则表达式regex时为真。比如:IF("hello"MATCHES"ell")MESSAGE("true")ENDIF("hello"MATCHES"ell")数字比较表达式IF(variableLESSnumber)IF(stringLESSnumber)IF(variableGREATERnumber)IF(stringGREATERnumber)IF(variableEQUALnumber)IF(stringEQUALnumber)按照字母表顺序进行比较IF(variableSTRLESSstring)IF(stringSTRLESSstring)IF(variableSTRGREATERstring)IF(stringSTRGREATERstring)IF(variableSTREQUALstring)IF(stringSTREQUALstring)一个小例子,用来判断平台差异:IF(WIN32)MESSAGE(STATUS“Thisiswindows.”)ELSE(WIN32)MESSAGE(STATUS“Thisisnotwindows”)ENDIF(WIN32)上述代码用来控制在不同的平台进行不同的控制,但是,阅读起来却并不是那么舒服,ELSE(WIN32)之类的语句很容易引起歧义。可以SET(CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTSON)这时候就可以写成:IF(WIN32)ELSE()ENDIF()配合ELSEIF使用,可能的写法是这样:IF(WIN32)#dosomethingrelatedtoWIN32ELSEIF(UNIX)#dosomethingrelatedtoUNIXELSEIF(APPLE)#dosomethingrelatedtoAPPLEENDIF(WIN32)WHILE语法:WHILE(condition)COMMAND1(ARGS...)COMMAND2(ARGS...)...ENDWHILE(condition)其真假判断条件可以参考IF指令FOREACHFOREACH指令的使用方法有三种形式:列表语法:FOREACH(loop_vararg1arg2...)COMMAND1(ARGS...)COMMAND2(ARGS...)...ENDFOREACH(loop_var)示例:AUX_SOURCE_DIRECTORY(.SRC_LIST)FOREACH(F${SRC_LIST})MESSAGE(${F})ENDFOREACH(F)范围语法:FOREACH(loop_varRANGEtotal)COMMAND1(ARGS...)COMMAND2(ARGS...)...ENDFOREACH(loop_var)示例:从0到total以1为步进FOREACH(VARRANGE10)MESSAGE(${VAR})ENDFOREACH(VAR)输出:012345678910范围和步进语法:FOREACH(loop_varRANGEstartstop[step])COMMAND1(ARGS...)COMMAND2(ARGS...)...ENDFOREACH(loop_var)从start开始到stop结束,以step为步进,注意:直到遇到ENDFOREACH指令,整个语句块才会得到真正的执行。FOREACH(ARANGE5153)MESSAGE(${A})ENDFOREACH(A)输出:581114cmake中如何生成动态库和静态库参考ADD_LIBRARY和SET_TARGET_PROPERTIES用法t3示例cmake中如何使用动态库和静态库(查找库的路径)参考INCLUDE_DIRECTORIES,LINK_DIRECTORIES,TARGET_LINK_LIBRARIES用法t4示例使用动态库或静态库t5示例如何使用cmake预定义的cmake模块(以FindCURL.cmake为例演示)t6示例如何使用自定义的cmake模块(编写了自定义的FindHELLO.cmake)注意读t5和t6的CMakeLists.txt和FindHELLO.cmake中的注释部分cmake中如何指定生成文件的输出路径如上ADD_SUBDIRECTORY的时候指定目标二进制文件输出路径(推荐使用下面这种)使用SET命令重新定义EXECUTABLE_OUTPUT_PATH和LIBRARY_OUTPUT_PATH变量来指定最终的二进制文件的位置SET(EXECUTABLE_OUTPUT_PATH${PROJECT_BINARY_DIR}/bin)SET(LIBRARY_OUTPUT_PATH${PROJECT_BINARY_DIR}/lib)上面的两条命令通常紧跟ADD_EXECUTABLE和ADD_LIBRARY,与其写在同一个CMakeLists.txt即可cmake中如何增加编译选项使用变量CMAKE_C_FLAGS添加C编译选项使用变量CMAKE_CXX_FLAGS添加C++编译选项使用ADD_DEFINITION添加cmake中如何增加头文件路径参考INCLUDE_DIRECTORIES命令用法cmake中如何在屏幕上打印信息参考MESSAGE用法cmake中如何给变量赋值参考SET和AUX_SOURCE_DIRECTORY用法建议:在Project根目录先建立build,然后在build文件夹内运行cmake..,这样就不会污染源代码,如果不想要这些自动生成的文件了,只要简单的删除build文件夹就可以转载于https://blog.csdn.net/wzzfeitian/article/details/40963457/

2020-8-9 1768 0
编程语言

很多程序需要检测客户端的IP地址,然后来授予相关的权限。比如数据库读写,文件读写,等等。其实还有一个很常见的应用,网站投票。网站投票始于2000年的左右,那时候.COM正热得发红,红得发紫。早期的投票只要投了就行可能技术牛人们还没有想到一个人会多投,那个时候反正上网的人也不多,后来慢慢的COKIE验证,IP验证等等都出来了,但是这些还不是最保险的,因为COOKIE是放在客户端的,可以伪造;IP可以用代理,也可以伪造请求。有人可能会提出异议,咱们后边再讨论。真的没有什么东西是百分百保险的,这不,湖南卫视前几年就作出更绝的,短信+QQ一票收费1元,刷的越多他们越高兴,刷吧呵呵。废话不多说,进入正题投票如果验证COOKIE的话,把cookies删掉继续投,如果验证IP的话,换个代理继续投。如果你说换代理很麻烦?那就伪造http请求中的IP信息好了。有人会说:IP验证是在TCP层完成的,不是HTTP层完成的,如果伪造IP的话可能连TCP的三次握手都完不成。我这里说的不是完全意义的伪造。如果你使用透明代理上网,那么在透明代理发送给服务器端的HTTP请求中会包含x-forward-for信息。例如:X-Forwarded-For:162.150.10.16那么我们只要在发给服务器端的http请求中加入X-Forwarded-For:162.150.10.16信息即可。例如下边一个请求:GEThttp://www.ahjinzhai.gov.cn/sdyxnx/vote.php?id=1HTTP/1.1Accept:image/gif,image/x-xbitmap,image/jpeg,image/pjpeg,application/x-shockwave-flash,application/vnd.ms-excel,application/vnd.ms-powerpoint,application/msword,*/*Referer:http://www.ahjinzhai.gov.cn/sdyxnx/Accept-Language:zh-cnAccept-Encoding:gzip,deflateUser-Agent:Mozilla/4.0(compatible;MSIE5.0;Windows98;DigExt;TencentTraveler)Host:www.ahjinzhai.gov.cnCookie:PHPSESSID=1847fc15020bc16b47ce250f457daab4Cache-Control:no-cacheX-Forwarded-For:162.150.10.16Pragma:no-cache上边的例子是安徽金寨门户网站中关于“十大优秀女性”评选的投票,1号选手是我班主任,当然要关注一下啦。猜测服务器端检测IP的代码可能如下:functionget_ip(){if(getenv('HTTP_CLIENT_IP')){gb_ip=getenv('HTTP_CLIENT_IP');}elseif(getenv('HTTP_X_FORWARDED_FOR')){$gb_ip=getenv('HTTP_X_FORWARDED_FOR');}elseif(getenv('REMOTE_ADDR')){$gb_ip=getenv('REMOTE_ADDR');}else{$gb_ip=$_SERVER['REMOTE_ADDR'];}returngb_ip=getenv('HTTP_CLIENT_IP');}elseif(getenv('HTTP_X_FORWARDED_FOR')){$gb_ip=getenv('HTTP_X_FORWARDED_FOR');}elseif(getenv('REMOTE_ADDR')){$gb_ip=getenv('REMOTE_ADDR');}else{$gb_ip=$_SERVER['REMOTE_ADDR'];}returngb_ip;还有一篇专门讲解如何获取在多级代理下客户端IP的方法http://www.blogjava.net/Alpha/archive/2006/07/12/57764.aspx对策:这种场合我们要折中一下,即只检测HTTP_CLIENT_IP,在ASP.NET中就该是只检测Request.UserHostAddress。总结:客户端IP地址检测有不同方法,不同的方法组合适合在不同的场合,只要程序员认真审视不同场合IP检测的方法,这里演示的方法会慢慢失效的。文后附了一篇文章,因为原文已经找不到了,无奈从GOOGLE的缓存中抢救回来,放在最后,原作者together,原文网址:点击这里。2006-10-20N年前CCTV的一场网络投票大战  话说几年前,CCTV搞了一个年度XX人物评选,与以往不同的是,这次评选采用网络投票的方式!彼时恰逢国内.com正热得发红,在这一次网络投票过程中,发生了一场“战争”。作为经历者之一,现在也许可以把它讲出来了。  先说投票人数,众所周知,我们的伟大祖国虽然人口众多,也不过屈屈十几亿而已,在当年的上网人数,也不超过一二亿,参加这次投票的,乐观点估计,撑死了也就30%吧,那就算2亿的30%,6000万吧。  再说候选人,聚集了国内企业界精英,如张xx,陶xx,倪xx,李xx等数十人,按正常的投票规律来看,这么多候选人,票数一分散,前几名的票数也不会超过1000万吧?  但事实让所有的人大掉眼镜!  投票开始没有几天,张xx,倪xx,陶xx的票数以每天一二百万的速度飞涨,形成了领跑的第一军团,后面的人是拍马也赶不上啊,望尘莫及!照这个速度,等到投票结束的时候,他们几个还不得每人都上亿票?要知道全中国一共才多少人啊,这不比国家统计局的数字还假嘛。  再说其中一位侯选人xxx,在国内也算是大有名头的人物,此时此刻在这一场投票中竟然跌落三甲,自然极不甘心,一手下大将急老板之所急,找到我们部门,要求为大老板的投票提供支援。要我们先分析一下前三名的投票机制,再帮老板弄弄。我一位兄弟,小B,听闻之后磨拳擦掌,誓要一展身手,此哥们平时就好搞搞反编译、破解啥的,C++功力一流。第一战:投票方式,列出了所有候选人的姓名,可以多选。最初的这场投票,是没有任何条件限制的,你点鼠标就可以了,不需要注册,更无其他限制。分析过后,小B仅用了半天时间,写了一个投票程序,自动发送http请求给CCTV网站,为显得不要太突出,在每次投票中,不只选老板一人,在他之外,每次在其它候选人中随机选一个人,这样就真真假假不好分辨了。公司里几百台电脑,马上全部装上该程序,24小时开机,开始猛力投票,老板的票数可就噌噌噌地上去了......,首战告捷第二战:可能CCTV也已经意识到了票数有点异常,毕竟里面也养了不少御用技术人员嘛,马上采取了补救措施,非注册用户不能投票!票数暂时增长放缓,但是马上大家都更新了程序,既然你让我注册,我就按你的HTML里的代码随机生成用户名和密码,来自动注册呗!票数又噌噌噌地上去了......第三战:CCTV有点傻了,赶紧想辙。马上做了一个要命的限制,从同一个IP段出来的所有用户,只能投一票!也就说是说,甭管你随机注册多少个用户,只能投一票。这一下可是立杆见影,其它三家一直领跑的票数马上就停了下来。我方这边,小B不愧是高手,马上修改程序,伪造IP数据包,每次发送过去的http信息中都是随机生成的IP。同时为加快投票速度,从单线程改为多线程。不过CCTV的服务器有点撑不住了,那几天访问他们网站的时候,那叫一个慢啊,跟蜗牛似的......终于,我们老板挤进了前三名,举公司欢呼啊。不过老板为人还是比较低调,不想当第一名,发话,保住第三名就可以了。因此我们就放慢了投票的速度。到最终整个投票结束的时候,老板恰好是第三名,一场大战终告结束。这件事情给我们的教训就是:第一,不能让人随便投票,得让用户先注册再投。第二,一个用户只能投一票。第三,在用户注册的时候,得加验证码。以防止作弊。第四,加验证码,还不能用静态的数字或字母,因为这样还是能作弊。得用随机生成的图片组合。第五,怎么防止用户随机生成伪IP包重复投票呢?转自http://www.cnblogs.com/x2048/articles/1794020.html

编程语言

我在Ubuntu16.04版本中使用终端安装MySQL5.7时,按照度娘的教程,搜索如何安装,大多是如下代码:sudoapt-getinstallmysql-serversudoapt-getinstallmysql-client12检查MySQL是否运行:sudonetstat-tap|grepmysql1如果成功安装,我的会显示如下内容:tcp00localhost:mysql*:*LISTEN18475/mysqld1PS:重启/打开/关闭MySQL的方法是:sudoservicemysqlrestart/start/stop就这两个命令就安装好了,可是我在安装过程中并没有出现要我写用户名和密码的地方,我一脸懵逼,完成后在终端输入mysql-uroot-p之后,要求我输入密码,可是我并不知道密码,随便输入之后,ERROR1045(28000):Accessdeniedforuser'root'@'localhost'(usingpassword:YES)1百度了三五个小时,解决方案五花八门,我最后使用有效的方法是:打开一个文件sudovim/etc/mysql/debian.cnf1在这个文件里面有着MySQL默认的用户名和用户密码,最最重要的是:用户名默认的不是root,而是debian-sys-maint,如下所示#AutomaticallygeneratedforDebianscripts.DONOTTOUCH![client]host=localhostuser=debian-sys-maintpassword=hGu99nJgoWcmCDKTsocket=/var/run/mysqld/mysqld.sock[mysql_upgrade]host=localhostuser=debian-sys-maintpassword=hGu99nJgoWcmCDKTsocket=/var/run/mysqld/mysqld.sockbasedir=/usr12345678910111213密码会随即给一个很复杂的,这个时候,要进入MySQL的话,就是需要在终端把root更改为debian-sys-maint,如下代码mysql-udebian-sys-maint-p1然后终端会提示你输入密码Enterpassword:1这是输入文件中的密码即可成功登陆。当然了,这之后就要修改密码了,毕竟密码太难记。经过度娘的指导,我所安装的版本是5.7,所以password字段已经被删除,取而代之的是authentication_string字段,所以要更改密码:mysql>updatemysql.usersetauthentication_string=password('password')whereuser='root'andHost='localhost';1如果显示:QueryOK,1rowaffected,1warning(0.00sec)Rowsmatched:1Changed:1Warnings:12则代表成功修改,之后需要*重启**MySQL,方可登录成功。顺便说一下删除MySQL的方法,省的之后再找度娘。代码如下:sudoapt-getautoremove--purgemysql-server-5.7sudoapt-getremovemysql-serversudoapt-getautoremovemysql-serversudoapt-getremovemysql-common1234上面的可能会有些是多余的,之后需要清理残余数据dpkg-l|grep^rc|awk'{print$2}'|sudoxargsdpkg-P12转载:http://blog.csdn.net/fr555wlj/article/details/54971412

2016-11-28 2718 0
编程语言

照着数据结构书敲的,内含快速插入排序算法#include<stdio.h>#include<stdlib.h>#defineMaxSize50typedefintElemType;typedefstruct{ElemTypedata[MaxSize];intlength;}SqList;/**创建一个线性表,使用了CreateList后就不需要使用InitList来初始化*线性表了**/voidCreateList(SqList*&L,ElemTypea[],intn){inti;L=(SqList*)malloc(sizeof(SqList));for(i=0;i<n;i++)L->data[i]=a[i];L->length=n;}/**初始化一个线性表,表中的数据是空的**/voidInitList(SqList*&L){L=(SqList*)malloc(sizeof(SqList));L->length=0;}/**销毁线性表,释放线性表中的内存**/voidDestoryList(SqList*&L){free(L);}/**判断线性表是否为空表,如果为空则返回真TRUE**/boolListEmpty(SqList*L){return(L->length);}/**返回当前线性表的长度Length**/intListLength(SqList*L){return(L->length);}/**输出线性表,顺序显示L中个节点的值域**/voidDispList(SqList*L){inti;for(i=0;i<L->length;i++)printf("%d\n",L->data[i]);printf("\n");}/**获取线性表中某个数据的元素值,用e返回**/boolGetElem(SqList*L,inti,ElemType&e){if(i<1||i>L->length)returnfalse;e=L->data[i-1];returntrue;}/**按值查找线性表中出现的位置(序号)**/intLocateElem(SqList*L,ElemTypee){inti=0;while(i<L->length&&L->data[i]!=e)i++;if(i>=L->length)return0;elsereturni+1;}/**插入数据元素**/boolListInsert(SqList*&L,inti,ElemTypee){intj;if(i<1||i>L->length+1)returnfalse;i--;for(j=L->length;j>i;j--)L->data[j]=L->data[j-1];L->data[i]=e;L->length++;returntrue;}/**删除数据元素**/boolListDelete(SqList*&L,inti,ElemType&e){intj;if(i<1||i>L->length)returnfalse;i--;e=L->data[i];for(j=i;j<L->length-1;j++)L->data[j]=L->data[j+1];L->length--;returntrue;}/**删除所有值等于x的元素*书本P35解法1*/voiddelnode1(SqList*&L,ElemTypex){intk=0,i;for(i=0;i<L->length;i++)if(L->data[i]!=x){L->data[k]=L->data[i];k++;}L->length=k;}/**插入排序算法*书本P36解法2*/voidmove2(SqList*&L){inti=0,j;j=L->length-1;ElemTypepivot=L->data[0];while(i<j){while(j>i&&L->data[j]>pivot)j--;L->data[i]=L->data[j];i++;while(i<j&&L->data[i]<=pivot)i++;L->data[j]=L->data[i];j--;}L->data[i]=pivot;printf("i=%d\n",i);}intmain(){inta[]={3,8,2,7,1,5,3,4,6,0};SqList*L;CreateList(L,a,10);//数组a的长度为10DispList(L);move2(L);printf("排序后:\n");DispList(L);}

2016-11-28 11748 0