[C++][CMake][流程控制]详细讲解
DieSnowK 2024-07-25 11:05:03 阅读 84
目录
1.条件判断1.基本表达式2.逻辑判断3.比较4.文件操作5.其他
2.循环1.foreach2.while
1.条件判断
在进行条件判断的时候,如果有多个条件,那么可以写多个<code>elseif,最后一个条件可以使用else
,但是开始和结束是必须要成对出现的,分别为:if
和endif
语法:
if(<condition>)
<commands>
elseif(<condition>) # 可选快, 可以重复
<commands>
else() # 可选快
<commands>
endif()
1.基本表达式
语法:
if(<expression>)
如果是基本表达式,expression
有以下三种情况:常量、变量、字符串
如果是1
, ON
, YES
, TRUE
, Y
, 非零值
,非空字符串
时,条件判断返回True
如果是0
, OFF
, NO
, FALSE
, N
, IGNORE
, NOTFOUND
,空字符串
时,条件判断返回False
2.逻辑判断
NOT:逻辑取反
if(NOT <condition>)
AND:逻辑与
if(<cond1> AND <cond2>)
OR:逻辑或
if(<cond1> OR <cond2>)
3.比较
基于数值的比较
if(<variable|string> LESS <variable|string>)
if(<variable|string> GREATER <variable|string>)
if(<variable|string> EQUAL <variable|string>)
if(<variable|string> LESS_EQUAL <variable|string>)
if(<variable|string> GREATER_EQUAL <variable|string>)
基于字符串的比较
if(<variable|string> STRLESS <variable|string>)
if(<variable|string> STRGREATER <variable|string>)
if(<variable|string> STREQUAL <variable|string>)
if(<variable|string> STRLESS_EQUAL <variable|string>)
if(<variable|string> STRGREATER_EQUAL <variable|string>)
4.文件操作
判断文件或者目录是否存在
if(EXISTS path-to-file-or-directory)
判断是不是目录:此处path
必须是绝对路径
if(IS_DIRECTORY path)
判断是不是软链接:此处的file-name
必须是绝对路径
if(IS_SYMLINK file-name)
判断是不是绝对路径
if(IS_ABSOLUTE path)
5.其他
判断某个元素是否在列表中:CMake版本要求 > 3.3
if(<variable|string> IN_LIST <variable>)
比较两个路径是否相等:CMake版本要求 > 3.24
if(<variable|string> PATH_EQUAL <variable|string>)
关于路径的比较其实就是两个字符串的比较,如果路径格式书写没有问题也可以通过下面这种方式进行比较
if(<variable|string> STREQUAL <variable|string>)
在书写某个路径的时候,可能由于误操作会多写几个分隔符,比如把/a/b/c
写成/a//b///c
,此时通过STREQUAL
对这两个字符串进行比较肯定是不相等的,但是通过PATH_EQUAL
去比较两个路径,得到的结果确实相等的,可以看下面的例子:
cmake_minimum_required(VERSION 3.26)
project(test)
if("/home//robin///Linux" PATH_EQUAL "/home/robin/Linux")
message("路径相等") # √
else()
message("路径不相等")
endif()
message(STATUS "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@")
if("/home//robin///Linux" STREQUAL "/home/robin/Linux")
message("路径相等")
else()
message("路径不相等") # √
endif()
结论:在进行路径比较的时候
如果使用PATH_EQUAL
可以自动剔除路径中多余的分割线然后再进行路径的对比使用STREQUAL
则只能进行字符串比较
2.循环
1.foreach
通过foreach
就可以对items
中的数据进行遍历,然后通过loop_var
将遍历到的当前的值取出语法:
foreach(<loop_var> <items>)
<commands>
endforeach()
loop_var
在取值的时候有以下几种用法:
foreach(<loop_var> RANGE <stop>)
参数:
RANGE
:关键字,表示要遍历范围stop
:这是一个正整数,表示范围的结束值,[0, stop]
loop_var
:存储每次循环取出的值 示例:
cmake_minimum_required(VERSION 3.2)
project(test)
foreach(item RANGE 10)
message(STATUS "当前遍历的值为: ${item}" )
endforeach()
foreach(<loop_var> RANGE <start> <stop> [<step>])
在遍历一个整数区间的时候,除了可以指定起始范围,还可以指定步长参数:
RANGE
:关键字,表示要遍历范围start
:这是一个正整数,表示范围的起始值,也就是说最小值为start
stop
:这是一个正整数,表示范围的结束值,也就是说最大值为stop
step
:控制每次遍历的时候以怎样的步长增长,默认为1,可以不设置loop_var
:存储每次循环取出的值 示例:
cmake_minimum_required(VERSION 3.2)
project(test)
foreach(item RANGE 10 30 2)
message(STATUS "当前遍历的值为: ${item}" )
endforeach()
foreach(<loop_var> IN [LISTS [<lists>]] [ITEMS [<items>]])
这是foreach
的另一个变体,通过这种方式可以对更加复杂的数据进行遍历,前两种方式只适用于对某个正整数范围内的遍历参数:
IN
:关键字,表示在xxx
里面LISTS
:关键字,对应的是列表list
,通过set、list
可以获得ITEMS
:关键字,对应的也是列表loop_var
:存储每次循环取出的值 示例1:
cmake_minimum_required(VERSION 3.2)
project(test)
# 创建 list
set(WORD a b c d)
set(NAME I am DieSnowK)
# 遍历 list
foreach(item IN LISTS WORD NAME)
message(STATUS "当前遍历的值为: ${item}" )
endforeach()
结果1
-- 当前遍历的值为: a
-- 当前遍历的值为: b
-- 当前遍历的值为: c
-- 当前遍历的值为: d
-- 当前遍历的值为: I
-- 当前遍历的值为: am
-- 当前遍历的值为: DieSnowK
示例2
cmake_minimum_required(VERSION 3.2)
project(test)
set(WORD a b c "d e f")
set(NAME I am DieSnowK)
foreach(item IN ITEMS ${WORD} ${NAME})
message(STATUS "当前遍历的值为: ${item}" )
endforeach()
结果2
-- 当前遍历的值为: a
-- 当前遍历的值为: b
-- 当前遍历的值为: c
-- 当前遍历的值为: d e f
-- 当前遍历的值为: I
-- 当前遍历的值为: am
-- 当前遍历的值为: DieSnowK
两种示例的区别:
遍历过程中将关键字LISTS
改成了ITEMS
,后边跟的还是一个或者多个列表只不过此时需要通过${}
将列表中的值取出 foreach(<loop_var>... IN ZIP_LISTS <lists>)
注意:CMake版本要求 > 3.17通过这种方式,遍历的还是一个或多个列表,可以理解为是方式3的加强版
因为通过上面的方式遍历多个列表,但是又想把指定列表中的元素取出来使用是做不到的,在这个加强版中就可以轻松实现 参数:
IN
:关键字,表示在xxx
里面ZIP_LISTS
:关键字,对应的是列表list
,通过set、list
可以获得loop_var
:存储每次循环取出的值,可以根据要遍历的列表的数量指定多个变量,用于存储对应的列表当前取出的那个值
如果指定了多个变量名,它们的数量应该和列表的数量相等如果只给出了一个loop_var
,那么它将一系列的loop_var_N
变量来存储对应列表中的当前项
loop_var_0
对应第一个列表loop_var_1
对应第二个列表以此类推… 示例:
cmake_minimum_required(VERSION 3.17)
project(test)
# 通过list给列表添加数据
list(APPEND WORD Die SnowK "Die SnowK")
list(APPEND NAME I am Die SnowK haha)
# 遍历列表
foreach(item1 item2 IN ZIP_LISTS WORD NAME)
message(STATUS "当前遍历的值为: item1 = ${item1}, item2=${item2}" )
endforeach()
message("=============================")
# 遍历列表
foreach(item IN ZIP_LISTS WORD NAME)
message(STATUS "当前遍历的值为: item1 = ${item_0}, item2=${item_1}" )
endforeach()
结果
-- 当前遍历的值为: item1 = Die, item2=I
-- 当前遍历的值为: item1 = SnowK, item2=am
-- 当前遍历的值为: item1 = Die SnowK, item2=Die
-- 当前遍历的值为: item1 = , item2=SnowK
-- 当前遍历的值为: item1 = , item2=haha
=============================
-- 当前遍历的值为: item1 = Die, item2=I
-- 当前遍历的值为: item1 = SnowK, item2=am
-- 当前遍历的值为: item1 = Die SnowK, item2=Die
-- 当前遍历的值为: item1 = , item2=SnowK
-- 当前遍历的值为: item1 = , item2=haha
2.while
语法:循环结束对应的条件判断的书写格式和if/elseif
是一样的
while(<condition>)
<commands>
endwhile()
示例:
cmake_minimum_required(VERSION 3.5)
project(test)
# 创建一个列表 NAME
set(NAME I am Die SnowK haha)
# 得到列表长度
list(LENGTH NAME LEN)
# 循环
while(${LEN} GREATER 0)
message(STATUS "names = ${NAME}")
# 弹出列表头部元素
list(POP_FRONT NAME)
# 更新列表长度
list(LENGTH NAME LEN)
endwhile()
结果
-- names = I;am;Die;SnowK;haha
-- names = am;Die;SnowK;haha
-- names = Die;SnowK;haha
-- names = SnowK;haha
-- names = haha
声明
本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。