精华内容
下载资源
问答
  • 如何判断状态标志位??OF和CF到底怎么计算???? 之前,一直被OF和CF这对神仙眷侣搞得云里雾里,总之三个字:看不懂!!! 不过不会也是要整滴~不然越拖越多,今天偶然发现其中的奥秘,不过也可能是以前看书不太...

    如何判断状态标志位??OF和CF到底怎么计算????

    之前,一直被OF和CF这对神仙眷侣搞得云里雾里,总之三个字:看不懂!!!

    不过不会也是要整滴~不然越拖越多,今天偶然发现其中的奥秘,不过也可能是以前看书不太仔细吧!哈哈!正文开始:

    先给出一个例题

    MOV AL , 7EH
    ADD AL , 5BH
    执行完这两条指令后,状态标志位的状态分别为??

    接下来,傻瓜式教学,仔细看一定会:
    7EH=0111 1110B
    5BH=0101 1011B
    两者相加得D9H=1101 1001B

    八位数加八位数得到一个八位数

    好的,我相信大家的实力,二进制是一定会计算的对吧!
    然后先判断其他的状态位:
    AF:D3位向D4位有进位吗? 我们计算的有,于是AF=1
    PF:低八位的所有位数中1的个数是偶数吗? 我们可以数一共有5个1,是奇数个,所以PF=0
    SF:最高位是1吗? 我们看到D9H的最高位是1,所以SF=1
    ZF:运算的结果等于0吗? 我们计算的D9H不等于0,所以ZF=0

    重头戏来了:

    CF:(简单方案)最高位向前有进位吗? 我们没有看到进位,所以CF=0

    但是:仅仅如此就是忽视了它最本质的意思,CF是无符号数进借位标志。
    这一句是什么意思呢?就是说计算的结果要和八位数中的最大值相比,看他有没有进位!怎么相比?八位数中的最大值是多少?FFH!!!D9H>FFH吗?不大于!所以结果没有超出标识范围,CF=0

    OF:有溢出吗?

    第一种方式:D9H作为有符号数为负!两个正数相加加成了负数,自然有溢出!所以OF=1
    第二种方式:D6位向D7位是否有进位,D7位向D8位是否有进位?同时进位或者同时不进位则OF=0;如果只有一个进位OF=1.如题:因为只有D6位向D7位进位,所以OF=1.
    第三种方式:OF是有符号数溢出标志!这是什么意思!看他有没有溢出呀,最大的有符号数是多少?7FH!D9H>7FH,所以OF=1.然后你说,不对啊,有符号数D9H=-59H,怎么就大于7FH了?我们将它这样理解:虽然有符号数的最大数为7FH,但是计算机并不能识别符号位,因此还是会将其看成无符号数,只是比较的时候比较这两个数,于是说D9H>7FH.

    综上所述:
    AF=1;CF=0;OF=1;PF=0;SF=1;ZF=0

    个人的一点理解,如果有不对的地方希望大神指正。

    展开全文
  • 数据溢出判断

    万次阅读 多人点赞 2019-05-03 15:58:20
    溢出概念 程序执行过程中,跑的都是数据,因此难免会有数据溢出的现象,那么, 1)数据溢出什么样子呢? 以byte类型为例,1byte...2)那当数据溢出时,计算机是如何判断溢出,进而修改OF标志位的? 计算机的计算方法...

    溢出概念

    程序执行过程中,跑的都是数据,因此难免会有数据溢出的现象,那么,
    1)数据溢出什么样子呢?
    以byte类型为例,1byte有8bit,如果最高位向前有进位,那么就表示数据溢出。
    eg:
      1000 0000
    +1000 0000
    ——————
    1 0000 0000
    我们还知道计算机有个溢出标志位OF,
    2)那当数据溢出时,计算机是如何判断溢出,进而修改OF标志位的?
    计算机的计算方法:OF=CF与次高位进位的异或值。CF是最高位(符号位)的进位,次高位进位是数据的最高位向符号位的进位。

    判断方法

    1、无符号数溢出判断
    其实很简单,就一句话:

    当最高为向更高位有进位(或借位)时产生溢出。

    2、有符号数溢出判断
    微机原理中的判断有符号数溢出规则:最高位进位状态⊕次高位进位状态=1,则溢出
    "⊕"表示异或:相同为0,相异为1
    那么上述判断规则翻译白话后为:最高位和次高位,一个有进位一个没有进位,则他们的状态异或值是1,则结果就有溢出。

    展开全文
  • 在中断服务函数中,如果设置标志位,然后其他函数判断标志位,需要设置全局变量来实现。全局变量的声明中需要添加修饰符volatile,防止编译器对变量进行优化,导致程序出错。 下面是volatile的用法说明: ...

    在中断服务函数中,如果设置标志位,然后其他函数判断标志位,需要设置全局变量来实现。全局变量的声明中需要添加修饰符volatile,防止编译器对变量进行优化,导致程序出错。


    下面是volatile的用法说明:

    volatile用于防止相关变量被优化

      例如对外部寄存器的读写。对有些外部设备的寄存器来说,读写操作可能都会引发一定硬件操作,但是如果不加volatile,编译器会把这些寄存器作为普通变量处理,例如连续多次的对同一地址写入,会被优化为只有最后一次的写入。实际上,网卡的数据发送,就是按顺序连续往一个同地址写入数据,如果被优化,网卡将不能正常驱动。对于外部寄存器的读写,经常用 XBYTE,其实你看一下XBYTE的原型就知道了,里面也是有个volatile的。
      另一个使用场合是中断。如果一个全局变量,在中断函数和普通函数里都用到过,那最好对这个变量加volatile修饰。否则普通函数里,可能会仅从寄存器里读取这个变量以便加快速度,而不去实际地址读取该变量。

      很多人对Volatile都不太了解,其实Volatile是由于编译器优化所造成的一个Bug而引入的关键字。

    int a = 10; 
    int b = a;
    int c = a; 

      理论上来讲每次使用a的时候都应该从a的地址来读取变量值,但是这存在一个效率问题,就是每次使用a都要去内存中取变量值,然后再通过系统总线传到CPU处理,这样开销会很大。所以那些编译器优化者故作聪明,把a读进CPU的cache里,像上面的代码,假如a在赋值期间没有被改变,就直接从CPU的cache里取a的副本来进行赋值。但是bug也显而易见,当a在赋给b之后,可能a已经被另一个线程改变而重新写回了内存,但这个线程并不知道,依旧按照原来的计划从CPU的cache里读a的副本进来赋值给c,结果不幸发生了。
      于是编译器的开发者为了补救这一bug,提供了一个Volatile让开发人员为他们的过失埋单,或者说提供给开发人员了一个选择效率的权利。当变量加上了Volatile时,编译器就老老实实的每次都从内存中读取这个变量值,否则就还按照优化的方案从cache里读。 

      volatile的本意是一般有两种说法--1.“暂态的”;2.“易变的”。这两种说法都有可行。但是究竟volatile是什么意思,现举例说明(以Keil-c与a51为例,例子来自Keil FQA),看完例子后你应该明白volatile的意思了,如果还不明白,那只好看一遍了。
      例1.

    复制代码
    void main (void)
    {
          volatile int i;
          int j;
    
          i = 1;    //1    不被优化 i=1
          i = 2;    //2    不被优化 i=1
          i = 3;    //3    不被优化 i=1
    
          j = 1;    //4    被优化
          j = 2;    //5    被优化
          j = 3;    //6    j = 3
    } 
    复制代码

      例2:函数:

    复制代码
    void func (void)
    {
          unsigned char xdata xdata_junk;
          unsigned char xdata *p = &xdata_junk;
          unsigned char t1, t2;
    
          t1 = *p;
          t2 = *p;
    } 
    复制代码

      编译的汇编为:

    复制代码
    0000 7E00      R       MOV       R6,#HIGH xdata_junk
    0002 7F00      R       MOV       R7,#LOW xdata_junk
    ;---- Variable 'p' assigned to Register 'R6/R7' ----
    
    0004 8F82              MOV       DPL,R7
    0006 8E83              MOV       DPH,R6
    
    ;!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 注意
    0008 E0                MOVX      A,@DPTR
    0009 F500      R       MOV       t1,A
    
    000B F500      R       MOV       t2,A
    ;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    000D 22                RET      
    复制代码

      将函数变为:

    复制代码
    void func (void)
    {
          volatile unsigned char xdata xdata_junk;
          volatile unsigned char xdata *p = &xdata_junk;
          unsigned char t1, t2;
    
          t1 = *p;
          t2 = *p;
    } 
    复制代码

      编译的汇编为:

    复制代码
    0000 7E00      R       MOV       R6,#HIGH xdata_junk
    0002 7F00      R       MOV       R7,#LOW xdata_junk
    ;---- Variable 'p' assigned to Register 'R6/R7' ----
    
    0004 8F82              MOV       DPL,R7
    0006 8E83              MOV       DPH,R6
    
    ;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    0008 E0                MOVX      A,@DPTR
    0009 F500      R       MOV       t1,A          ;a处
    
    000B E0                MOVX      A,@DPTR
    000C F500      R       MOV       t2,A
    ;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    
    000E 22                RET 
    复制代码

      比较结果可以看出来,未用volatile关键字时,只从*p所指的地址读一次如在a处*p的内容有变化,则t2得到的则不是真正*p的内容。
      例3:

    复制代码
    volatile unsigned char bdata var;    // use volatile keyword here
    sbit var_0 = var^0;
    sbit var_1 = var^1;
    unsigned char xdata values[10];
    
    void main (void)    
    {
        unsigned char i;
        
        for (i = 0; i < sizeof (values); i++)    
        {
            var = values[i];
            if (var_0)    
            {
                var_1 = 1;          // a处
                values[i] = var;    // without the volatile keyword, the compiler
                                    // assumes that 'var' is unmodified and does not
                                    // reload the variable content.
            }
        }
    } 
    复制代码

      在此例中,如在a处到下一句运行前,var如有变化则不会,如var=0xff; 则在values[i] = var;得到的还是values[i] = 1;

     

      应用举例:
      例1.

    #define DBYTE ((unsigned char volatile data    *) 0)

      说明:此处不用volatile关键字,可能得不到真正的内容。

      例2.

    复制代码
    #define TEST_VOLATILE_C 
    
    //***************************************************************
    // verwendete Include Dateien
    //***************************************************************
    #if __C51__ < 600
        #error: !! Keil 版本不正确
    #endif
    
    //***************************************************************
    // 函数 void v_IntOccured(void)
    //***************************************************************
    extern void v_IntOccured(void);
    
    //***************************************************************
    // 变量定义
    //***************************************************************
    char xdata cValue1;            //全局xdata
    char volatile xdata cValue2;   //全局xdata
    
    //***************************************************************
    // 函数: v_ExtInt0()
    // 版本:
    // 参数:
    // 用途:cValue1++,cValue2++
    //***************************************************************
    void v_ExtInt0(void) interrupt 0 
    {
        cValue1++;
        cValue2++; 
    }        
    
    //***************************************************************
    // 函数: main()
    // 版本:
    // 参数:
    // 用途:测试volatile
    //***************************************************************
    void main() 
    {
        char cErg;
        
        //1. 使cErg=cValue1;
        cErg = cValue1;
        
        //2. 在此处仿真时手动产生中断INT0,使cValue1++; cValue2++
        if (cValue1 != cErg)
            v_IntOccured();
        
        //3. 使cErg=cValue2;
        cErg = cValue2;
        
        //4. 在此处仿真时手动产生中断INT0,使cValue1++; cValue2++
        if (cValue2 != cErg)
            v_IntOccured();
        
        //5. 完成
        while (1);
    }
    
    //***************************************************************
    // 函数: v_IntOccured()
    // 版本:
    // 参数:
    // 用途: 死循环
    //***************************************************************
    void v_IntOccured() 
    {
        while(1);
    } 
    复制代码

      仿真可以看出,在没有用volatile时,即2处,程序不能进入v_IntOccured(); 但在4处可以进入v_IntOccured();

    展开全文
  • bash-shell高级编程--条件判断

    千次阅读 2020-02-01 18:04:49
    条件判断 每一个完整并且合理的程序语言都具有条件判断的功能,并且可以根据条件判断的结果做下一步处理,bash中有test命令,有各种中括号和圆括号操作,和if/then结构 条件测试结构 使用if/then结构判断命令列表的...

    条件判断

    每一个完整并且合理的程序语言都具有条件判断的功能,并且可以根据条件判断的结果做下一步处理,bash中有test命令,有各种中括号和圆括号操作,和if/then结构

    条件测试结构

    • 使用if/then结构判断命令列表的退出码状态是否为0,如果成功的话,那么就执行接下来一个或多个命令。
    • 有一个专有命令[(左括号,特殊字符),这个命令与test命令等价,并且处于效率上的考虑,这是一个内建命令,这个命令把它的参数作为表达式或者文件测试,并且根据比较的结果返回一个退出状态码(0表示真,1表示假)
    • 在版本2.02的bash中,引入了[[....]]扩展测试命令,因为这种表现形式可能对某些语言的程序员来说更熟悉一些,注意[[]]是一个关键字,并不是一个命令,并且bash会将[[ $a -lt $b ]]看成单独的元素,并且返回一个退出状态码。

    if命令不仅可以测试中括号中的条件,可以测试任何命令

    if cmp a b &> /dev/null # 禁止输出.
    then echo "Files a and b are identical."
    else echo "Files a and b differ."
    fi
    
    # 非常有用的"if-grep"结构:
    # ------------------------
    if grep -q Bash file
    then echo "File contains at least one occurrence of Bash."
    fi
    
    word=Linux
    letter_sequence=inu
    if echo "$word" | grep -q "$letter_sequence"
    # "-q" 选项是用来禁止输出的.
    then
     echo "$letter_sequence found in $word"
    else
     echo "$letter_sequence not found in $word"
    fi
    
    ## 执行成功,进到if条件判断下
    if COMMAND_WHOSE_EXIT_STATUS_IS_0_UNLESS_ERROR_OCCURRED
    then echo "Command succeeded."
    else echo "Command failed."
    fi
    
    • 一个if/then结构可以包含嵌套的比较操作和条件判断操作
    if echo "Next *if* is part of the comparison for the first *if*."
      if [[ $comparison = "integer" ]]
        then (( a < b ))
      else
        [[ $a < $b ]]
      fi
    then
     echo '$a is less than $b'
    fi
    

    什么是真

    #!/bin/bash
    
    # 小技巧:
    # 如果你不能够确定一个特定的条件该如何进行判断,
    #+ 那么就使用if-test结构.
    echo
    
    echo "Testing \"0\""
    if [ 0 ]
    # zero
    then
     echo "0 is true."
    else
     echo "0 is false."
    fi
    # 0 为真.
    echo
    
    echo "Testing \"1\""
    if [ 1 ]
    # one
    then
     echo "1 is true."
    else
     echo "1 is false."
    fi
    # 1 为真.
    echo
     
    echo "Testing \"-1\""
    if [ -1 ]
    # 负1
    then
     echo "-1 is true."
    else
     echo "-1 is false."
    fi
    # -1 为真.
    echo
    
    echo "Testing \"NULL\""
    if [ ]
    # NULL (空状态)
    then
     echo "NULL is true."
    else
     echo "NULL is false."
    fi
    # NULL 为假.
    echo
    
    echo "Testing \"xyz\""
    if [ xyz ]
    # 字符串
    then
      echo "Random string is true."
    else
     echo "Random string is false."
    fi
    # 随便的一串字符为真.
    
    echo
    
    echo "Testing \"\$xyz\""
    if [ $xyz ]
    # 判断$xyz是否为null, 但是...
    
    # 这只是一个未初始化的变量.
    then
     echo "Uninitialized variable is true."
    else
     echo "Uninitialized variable is false."
    fi
    # 未定义的初始化为假.
    
    echo
    
    echo "Testing \"-n \$xyz\""
    if [ -n "$xyz" ]
    # 更加正规的条件检查.
    then
     echo "Uninitialized variable is true."
    else
     echo "Uninitialized variable is false."
    fi
    # 未初始化的变量为假.
    
    echo
    xyz=
    # 初始化了, 但是赋null值.
    
    echo "Testing \"-n \$xyz\""
    if [ -n "$xyz" ]
    then
     echo "Null variable is true."
    else
     echo "Null variable is false."
    fi
    # null变量为假.
    echo
    # 什么时候"false"为真?
    
    echo "Testing \"false\""
    if [ "false" ]
    # 看起来"false"只不过是一个字符串而已.
    then
     echo "\"false\" is true." #+ 并且条件判断的结果为真.
    else
     echo "\"false\" is false."
    fi
    # "false" 为真.
     
    echo
    
    echo "Testing \"\$false\"" # 再来一个, 未初始化的变量.
    if [ "$false" ]
    then
     echo "\"\$false\" is true."
    else
     echo "\"\$false\" is false."
    fi
    # "$false" 为假.
    # 现在, 我们得到了预期的结果.
    # 如果我们测试以下为初始化的变量"$true"会发生什么呢?
    echo
    exit 0
    

    执行结果

    andrew@andrew:/work/bash/src$ bash if_true.sh 
    
    Testing "0"
    0 is true.
    
    Testing "1"
    1 is true.
    
    Testing "-1"
    -1 is true.
    
    Testing "NULL"
    NULL is false.
    
    Testing "xyz"
    Random string is true.
    
    Testing "$xyz"
    Uninitialized variable is false.
    
    Testing "-n $xyz"
    Uninitialized variable is false.
    
    Testing "-n $xyz"
    Null variable is false.
    
    Testing "false"
    "false" is true.
    
    Testing "$false"
    "$false" is false.
    

    如果ifthen在条件判断的同一行上的话,必须使用分号结束if表达式,ifthen都是关键字。关键字(或者命令)如果作为表达式的开头,并且如果想在同一行上再写一个新的表达式的话,那么必须使用分号来结束上一句表达式。

    if [ -x "$filename" ]; then

    else if 和elif

    elifelse if的缩写形式,作用是在外部的判断结构中在嵌入一个内部的if/then结构

    if [ condition1 ]
    then
      command1
      command2
      command3
    elif [ condition2 ]
    # 与else if一样
    then
      command4
      command5
    else
      default-command
    fi
    

    if test condition结构与if [ condition ]完全相同。

    test命令在Bash中是内建命令, 用来测试文件类型, 或者用来比较字符串. 因此, 在Bash
    脚本中, test命令并不会调用外部的 /usr/bin/test 中的test命令, 这是sh-utils工具包中
    的一部分. 同样的, [也并不会调用 /usr/bin/[ , 这是 /usr/bin/test 的符号链接.

    test/usr/bin/test, [], 和/usr/bin/[都是等价的命令

    #!/bin/bash
    echo
    if test -z "$1"
    then
     echo "No command-line arguments."
    else
     echo "First command-line argument is $1."
    fi
    echo
    if /usr/bin/test -z "$1"
    # 与内建的"test"命令结果相同.
    then
     echo "No command-line arguments."
    else
     echo "First command-line argument is $1."
    fi
    echo
    if [ -z "$1" ]
    # 与上边的代码块作用相同.
    #
    if [ -z "$1"
    应该能够运行, 但是...
    #+ Bash报错, 提示缺少关闭条件测试的右中括号.
    then
     echo "No command-line arguments."
    else
     echo "First command-line argument is $1."
    fi
    echo
    if /usr/bin/[ -z "$1" ]
    # 再来一个, 与上边的代码块作用相同.
    # if /usr/bin/[ -z "$1"
    # 能够工作, 但是还是给出一个错误消息.
    #
    # 注意:
    #在版本3.x的Bash中, 这个bug已经被修正了.
    then
     echo "No command-line arguments."
    else
     echo "First command-line argument is $1."
    fi
    echo
    exit 0
    

    [[]]之间的所有的字符都不会发生文件名扩展或者单词分割,但是会发生参数扩展和命令替换

    使用[[]]而不是[],能够防止脚本中的许多逻辑错误,比如, &&,||, < , 和>操作符能够正常存在于[[]]条件判断结构中,但是如果出现在[]结构中的话,会报错。

    if后面也不一定得跟test命令或者用于条件判断的中括号([]或者[[]])

    dir=/home/bozo
    
    if cd "$dir" 2>/dev/null; then # "2>/dev/null" 会隐藏错误信息.
     echo "Now in $dir."
    else
     echo "Can't change to $dir."
    fi
    

    if command结构将会返回command的退出码。

    在中括号中的条件判断也不是非if不可,也可以使用列表结构

    var1=20
    var2=22
    [ "$var1" -ne "$var2" ] && echo "$var1 is not equal to $var2"
    
    home=/home/bozo
    [ -d "$home" ] || echo "$home directory does not exist."
    

    算术测试使用(())

    #!/bin/bash
    # 算术测试.
    # (( ... ))结构可以用来计算并测试算术表达式的结果.
    # 退出状态将会与[ ... ]结构完全相反!
    (( 0 ))
    echo "Exit status of \"(( 0 ))\" is $?."
     (( 1 ))
     echo "Exit status of \"(( 1 ))\" is $?."
    (( 5 > 4 ))
    echo "Exit status of \"(( 5 > 4 ))\" is $?."
    (( 5 > 9 ))
    echo "Exit status of \"(( 5 > 9 ))\" is $?."
    (( 5 - 5 ))
    echo "Exit status of \"(( 5 - 5 ))\" is $?."
    (( 5 / 4 ))
    echo "Exit status of \"(( 5 / 4 ))\" is $?."
    (( 1 / 2 ))
    echo "Exit status of \"(( 1 / 2 ))\" is $?."
    (( 1 / 0 )) 2>/dev/null
    #
    echo "Exit status of \"(( 1 / 0 ))\" is $?."
    # "2>/dev/null"起了什么作用?
    # 如果这句被删除会怎样?
    # 尝试删除这句, 然后在运行这个脚本.
    exit 0
    

    条件测试操作符

    条件成立返回真,调试不成立时返回假
    -e
    文件存在

    -a
    文件存在
    这个选项的效果与-e相同. 但是它已经被"弃用"了, 并且不鼓励使用.

    -f
    表示这个文件是一个 一般 文件(并不是目录或者设备文件)

    -s
    文件大小不为零

    -d
    表示这是一个目录

    -b
    表示这是一个块设备(软盘, 光驱, 等等.)

    -c
    表示这是一个字符设备(键盘, modem, 声卡, 等等.)

    -p
    这个文件是一个管道

    -h
    这是一个符号链接

    -L
    这是一个符号链接

    -S
    表示这是一个socket

    -t
    文件(描述符)被关联到一个终端设备上
    这个测试选项一般被用来检测脚本中的 stdin ( [终端.-t 0 ] )或者 stdout ( [``-t 1 ] )是否来自于一个

    -r
    文件是否具有可读权限( 指的是正在运行这个测试命令的用户是否具有读权限)

    -w
    文件是否具有可写权限(指的是正在运行这个测试命令的用户是否具有写权限)

    -x
    文件是否具有可执行权限(指的是正在运行这个测试命令的用户是否具有可执行权限)

    -g
    set-group-id(sgid)标记被设置到文件或目录上
    如果目录具有 sgid 标记的话, 那么在这个目录下所创建的文件将属于拥有这个目录的用户组, 而
    不必是创建这个文件的用户组. 这个特性对于在一个工作组中共享目录非常有用.

    -u
    set-user-id (suid)标记被设置到文件上,如果一个root用户所拥有的二进制可执行文件设置了 set-user-id 标记位的话, 那么普通用户也会以root权限来运行这个文件. 这对于需要访问系统硬件的执行程序(比如pppd和cdrecord)
    常有用. 如果没有suid标志的话, 这些二进制执行程序是不能够被非root用户调用的.

    -rwsr-xr-t  1 root  178236 Oct  2   2000   /usr/sbin/pppd
    

    对于设置了 suid 标志的文件, 在它的权限列中将会以s 表示.

    -k
    设置 粘贴位
    对于"粘贴位"的一般了解, save-text-mode标志是一个文件权限的特殊类型. 如果文件设置了这个标志, 那么这个文件将会被保存到缓存中, 这样可以提高访问速度. 粘贴位如果设置在目录中, 那么它将限制写权限. 对于设置了粘贴位的文件或目录, 在它们的权限标记列中将会显示 t.
    drwxrwxrwt 7 root 1024 May 19 21:26 tmp/
    如果用户并不拥有这个设置了粘贴位的目录, 但是他在这个目录下具有写权限, 那么这个用户只能在这个目录下删除自己所拥有的文件. 这将有效的防止用户在一个公共目录中不慎覆盖或者删除别人的文件. 比如说 /tmp 目录. (当然, 目录的所有者或者 root用户可以随意删除或重命名其中的文件.)

    -O
    判断你是否是文件的拥有者

    -G
    文件的group-id是否与你的相同

    -N
    从文件上一次被读取到现在为止, 文件是否被修改过

    f1 -nt f2
    文件 f1 比文件 f2

    f1 -ot f2
    文件 f1 比文件 f2
    f1 -ef f2文件 f1 和文件 f2 是相同文件的硬链接

    !
    “非” – 反转上边所有测试的结果(如果没给出条件, 那么返回真).

    测试断掉的链接文件

    #!/bin/bash
    # 一个可以测试链接断掉的符号链接的文件,并且可以输出它们指向的文件
    # 以便于它们可以把输出提供给xargs来进行处理 :)
    # 比如. broken-link.sh /somedir /someotherdir|xargs rm
    #
    #下边的方法, 不管怎么说, 都是一种更好的办法:
    #
    #find "somedir" -type l -print0|\
    #xargs -r0 file|\
    #grep "broken symbolic"|
    #sed -e 's/^\|: *broken symbolic.*$/"/g'
    #
    #但这不是一个纯粹的bash脚本, 最起码现在不是.
    #注意: 谨防在/proc文件系统和任何死循环链接中使用!
    ##############################################################
    #如果没有参数被传递到脚本中, 那么就使用
    #当前目录. 否则就是用传递进来的参数作为目录
    #来搜索.
    ####################
    [ $# -eq 0 ] && directorys=`pwd` || directorys=$@
    
    #编写函数linkchk用来检查传递进来的目录或文件是否是链接,
    #并判断这些文件或目录是否存在. 然后打印它们所指向的文件.
    #如果传递进来的元素包含子目录,
    #那么把子目录也放到linkcheck函数中处理, 这样就达到了递归的目的.
    ##########
    # 如果是软连接,则输出,如果是目录就进行地递归
    linkchk () {
        for element in $1/*; do
            [ -h "$element" -a ! -e "$element" ] && echo \"$element\"
            [ -d "$element" ] && linkchk $element
            # 当然, '-h'用来测试符号链接, '-d'用来测试目录.
        done
    }
    # 把每个传递到脚本的参数都送到linkchk函数中进行处理,
    # 检查是否有可用目录. 如果没有, 那么就打印错误消息和
    # 使用信息.
    ################
    for directory in $directorys; do
        if [ -d $directory ]
            then linkchk $directory
            else
                echo "$directory is not a directory"
                echo "Usage: $0 dir1 dir2 ..."
        fi
       done
    exit 0
    
    # 创建一个新文件 name
    andrew@andrew:/work/bash/src$ touch name
    # 为name创建符号链接
    andrew@andrew:/work/bash/src$ ln -s name aaa
    # 删除name文件, aaa将会变成丢失链接文件的符号链接
    andrew@andrew:/work/bash/src$ rm name
    # 查看aaa为执行当前目录下的name的符号链接文件
    andrew@andrew:/work/bash/src$ ls -l
    总用量 44
    lrwxrwxrwx 1 andrew andrew    4 2月   1 13:20 aaa -> name
    -rwxrwxr-x 1 andrew andrew 8656 1月  30 14:46 a.out
    -rw-rw-r-- 1 andrew andrew 1887 2月   1 13:08 broken_link.sh
    -rw-rw-r-- 1 andrew andrew  322 1月  29 13:08 echo_unique.sh
    -rw-rw-r-- 1 andrew andrew 1513 1月  29 15:55 escape_charater.sh
    -rw-rw-r-- 1 andrew andrew  279 1月  30 13:48 exit_example.sh
    -rw-rw-r-- 1 andrew andrew  199 2月   1 11:52 if_else_more.sh
    -rw-rw-r-- 1 andrew andrew 1946 1月  30 21:03 if_true.sh
    -rw-rw-r-- 1 andrew andrew  337 1月  29 14:02 single_quotation_mark.sh
    -rw-rw-r-- 1 andrew andrew  864 2月   1 12:00 test.c
    # 调用脚本清除当前文件夹中,丢失链接文件的符号链接
    andrew@andrew:/work/bash/src$ bash broken_link.sh ./ | xargs rm
    andrew@andrew:/work/bash/src$ ls -l
    总用量 44
    -rwxrwxr-x 1 andrew andrew 8656 1月  30 14:46 a.out
    -rw-rw-r-- 1 andrew andrew 1887 2月   1 13:08 broken_link.sh
    -rw-rw-r-- 1 andrew andrew  322 1月  29 13:08 echo_unique.sh
    -rw-rw-r-- 1 andrew andrew 1513 1月  29 15:55 escape_charater.sh
    -rw-rw-r-- 1 andrew andrew  279 1月  30 13:48 exit_example.sh
    -rw-rw-r-- 1 andrew andrew  199 2月   1 11:52 if_else_more.sh
    -rw-rw-r-- 1 andrew andrew 1946 1月  30 21:03 if_true.sh
    -rw-rw-r-- 1 andrew andrew  337 1月  29 14:02 single_quotation_mark.sh
    -rw-rw-r-- 1 andrew andrew  864 2月   1 12:00 test.c
    
    • 在将suid标记设置到二进制可执行文件的时候, 一定要小心. 因为这可能会引发安全漏洞.
      但是suid标记不会影响shell脚本.
    • 在当代UNIX系统中, 文件中已经不使用粘贴位了, 粘贴位只使用在目录中.

    其他比较操作符

    二元比较操作符,用来比较两个变量或者数字。
    整数比较
    -eq
    等于
    if [ "$a" -eq "$b" ]

    -ne
    不等于
    if [ "$a" -ne "$b" ]

    -gt
    大于
    if [ “ a " − g t " a" -gt " a"gt"b” ]

    -ge
    大于等于
    if [ "$a" -ge "$b" ]

    -lt
    小于
    if [ "$a" -lt "$b" ]

    -le
    小于等于
    if [ "$a" -le "$b" ]

    <
    小于(在双括号中使用)
    (("$a" < "$b"))

    <=
    小于等于(在双括号中使用)
    (("$a" <= "$b"))

    >

    大于(在双括号中使用)
    (("$a" > "$b"))

    >=
    大于等于(在双括号中使用)
    下一页
    (("$a" >= "$b"))

    字符串比较
    =
    等于

    if [ "$a" = "$b" ]

    ==
    等于
    if [ "$a" == "$b" ]
    =等价.
    ==比较操作符在双中括号对和单中括号对中的行为是不同的.

    [[ $a == z* ]]
    # 如果$a以"z"开头(模式匹配)那么结果将为真
    [[ $a == "z*" ]] # 如果$a与z*相等(就是字面意思完全一样), 那么结果为真.
    [ $a == z* ]
    # 文件扩展匹配(file globbing)和单词分割有效.
    [ "$a" == "z*" ] # 如果$a与z*相等(就是字面意思完全一样), 那么结果为真.
    

    !=
    不等号
    if [ "$a" != "$b" ]
    这个操作符将在[[ … ]]结构中使用模式匹配.

    <
    小于, 按照ASCII字符进行排序
    if [[ "$a" < "$b" ]]
    if [ "$a" \< "$b" ]
    注意"<"使用在 [ ] 结构中的时候需要被转义.

    >

    大于, 按照ASCII字符进行排序
    if [[ "$a" > "$b" ]]
    if [ "$a" \> "$b" ]
    注意">"使用在 [ ] 结构中的时候需要被转义.

    -z
    字符串为"null", 意思就是字符串长度为零

    -n
    字符串不为"null".

    #!/bin/bash
    a=4
    b=5
    # 这里的"a"和"b"既可以被认为是整型也可被认为是字符串.
    # 这里在算术比较与字符串比较之间是容易让人产生混淆,
    #+ 因为Bash变量并不是强类型的.
    # Bash允许对于变量进行整形操作与比较操作.
    #+ 但前提是变量中只能包含数字字符.
    # 不管怎么样, 还是要小心.
    echo
    # 按照整数进行比较
    if [ "$a" -ne "$b" ]
    then
     echo "$a is not equal to $b"
     echo "(arithmetic comparison)"
    fi
    
    echo
    
    # 按照字符串进行比较
    if [ "$a" != "$b" ]
    then
     echo "$a is not equal to $b."
     echo "(string comparison)"
     # "4" != "5"
    # ASCII 52 != ASCII 53
    fi
    # 在这个特定的例子中, "-ne"和"!="都可以.
    echo
    exit 0
    

    检查字符串是否为NULL

    该脚本只在ubuntu 16.04上测试过,在其他系统上使用记得先使用shellcheck对脚本进行语法检查

    #!/bin/bash
    # str-test.sh: 检查null字符串和未引用的字符串,
    #+ but not strings and sealing wax, not to mention cabbages and kings . . .
    #+ 但不是字符串和封蜡, 也并没有提到卷心菜和国王. . . ??? (没看懂, rojy bug)
    
    # 使用 if [ ... ]
    
    # 如果字符串并没有被初始化, 那么它里面的值未定义.
    # 这种状态被称为"null" (注意这与零值不同).
    
    if [ -n $string1 ]
    # $string1 没有被声明和初始化.
     then
     echo "String \"string1\" is not null."
     else
     echo "String \"string1\" is null."
    fi
    # 错误的结果.
    # 显示$string1为非null, 虽然这个变量并没有被初始化.
    
    
    echo
    
    
    # 让我们再试一下.
    
    if [ -n "$string1" ] # 这次$string1被引号扩起来了.
    then
     echo "String \"string1\" is not null."
    else
     echo "String \"string1\" is null."
    fi
    # 注意一定要将引用的字符放到中括号结构中!33 
    
    echo
    
    
    if [ $string1 ]
    # 这次, 就一个$string1, 什么都不加.
    then
     echo "String \"string1\" is not null."
    else
     echo "String \"string1\" is null."
    fi
    # 这种情况运行的非常好.
    # [ ] 测试操作符能够独立检查string是否为null.
    # 然而, 使用("$string1")是一种非常好的习惯.
    #
    # 就像Stephane Chazelas所指出的,
    #if [ $string1 ]只有一个参数, "]"
    #if [ "$string1" ] 有两个参数, 一个是空的"$string1", 另一个是"]"
    
    echo
    string1=initialized
    
    if [ $string1 ]
    # 再来, 还是只有$string1, 什么都不加.
    then
     echo "String \"string1\" is not null."
    else
     echo "String \"string1\" is null."
    fi
    # 再来试一下, 给出了正确的结果.
    # 再强调一下, 使用引用的("$string1")还是更好一些, 原因我们上边已经说过了.
    
    
    string1="a = b"
    
    if [ $string1 ]
    # 再来, 还是只有$string1, 什么都不加.
    then
     echo "String \"string1\" is not null."
    else
     echo "String \"string1\" is null."
    fi
    # 未引用的"$string1", 这回给出了错误的结果!
    
    exit 0
    
    

    执行结果

    andrew@andrew:/work/bash/src$ bash str_test.sh 
    String "string1" is not null.
    
    String "string1" is null.
    
    String "string1" is null.
    
    String "string1" is not null.
    String "string1" is null.
    
    #!/bin/bash
    # zmore
    
    #使用'more'来查看gzip文件
    
    NOARGS=65
    NOTFOUND=66
    NOTGZIP=67
    
    if [ $# -eq 0 ] # 与if [ -z "$1" ]效果相同
    # (译者注: 上边这句注释有问题), $1是可以存在的, 可以为空, 如: zmore "" arg2 arg3
     then
     echo "Usage: `basename $0` filename" >&2
    # 错误消息输出到stderr.
     exit $NOARGS
    # 返回65作为脚本的退出状态的值(错误码).
    fi
    
    filename=$1
    
    if [ ! -f "$filename" ]
    # 将$filename引用起来, 这样允许其中包含空白字符.
    then
     echo "File $filename not found!" >&2
    # 错误消息输出到stderr.
    exit $NOTFOUND
    fi
    
    if [ ${filename##*.} != "gz" ]
    # 在变量替换中使用中括号结构.
    then31  echo "File $1 is not a gzipped file!"
     exit $NOTGZIP
    fi
    
    zcat $1 | more
    
    # 使用过滤命令'more.'
    # 当然, 如果你愿意, 也可以使用'less'.
    exit $?
    # 脚本将把管道的退出状态作为返回值.
    # 事实上, 也不一定非要加上"exit $?", 因为在任何情况下,
    # 脚本都会将最后一条命令的退出状态作为返回值.
    

    -a
    逻辑与exp1 -a exp2, 如果表达式exp1exp2都为真的话, 那么结果为真.

    -o
    逻辑或exp1 -o exp2, 如果表达式exp1exp2中至少有一个为真的话, 那么结果为真.

    嵌套的if/then条件测试

    可以通过if/then结构来使用嵌套的条件测试,最终的结果和上面使用的&&混合比较操作符的结果是相同的。

    if [ condition1 ]
    then
     if [ condition2 ]
     then
    	do-something # But only if both "condition1" and "condition2" valid.
     fi
    fi
    

    检测你对测试知识的掌握

    if [ -f $HOME/.Xclients ]; then
     exec $HOME/.Xclients
    elif [ -f /etc/X11/xinit/Xclients ]; then
     exec /etc/X11/xinit/Xclients
    else
        # 失败后的安全设置. 虽然我们永远都不会走到这来.
        # (我们在Xclients中也提供了相同的机制) 保证它不会被破坏.
        xclock -geometry 100x100-5+5 &
        xterm -geometry 80x50-50+150 &
        if [ -f /usr/bin/netscape -a -f /usr/share/doc/HTML/index.html ]; then
    
        netscape /usr/share/doc/HTML/index.html &
    fi
    fi
    
    展开全文
  • 汇编中一些标志位的含义

    万次阅读 2016-01-23 21:21:25
    汇编语言标志位 含义 NV UP EI NG NZ AC PE CY 股沟了一下,终于知道了缩写是什么意思了。 Overflow of = OV NV [No Overflow] Direction df = DN (decrement) UP (increment) Int
  • 数据挖掘笔记-文本情感简单判断

    千次阅读 2014-10-04 12:42:04
    文本情感简单判断的过程大概如下:经过预处理后的文本,首先识别不同极性类别的特征项,通过构建好的情感词表(褒义词、贬义词)、否定词词表、程度副词词表以及反问标记词表做相应处理,获取该条文本中每个特征项...
  •  其实归结起来,补码的溢出判断规则就一话:   同号数相加如果结果的符号位和两加数不同,既是溢出。   这自然说明了:   ⑴不是同号数相加,则不可能溢出;   ⑵同号数相加有可能溢出; ...
  • 无符号数和有符号数的溢出判断

    万次阅读 多人点赞 2018-05-25 21:09:35
    无符号数溢出判断:其实很简单,就一话: 当最高为向更高位有进位(或借位)时产生溢出。就像这样: 有符号数溢出判断: 高潮来了: 最高位进位状态⊕次高位进位状态=1,则溢出怎么理解呢?首先要知道异或是...
  • Android源码用到的Flag设置标志位机制

    千次阅读 2016-11-23 12:04:50
    日常编码中我们设置状态,如果是一种情形的两种状态,可以用0或者1来区分,如果是多种情形每种情形还有多个状态,我们可以利用android这套设置标志位机制,它的原理就是利用int不同位表示不同的情形,再利用这些位所...
  • php判断网页 是否是 Android webview加载

    千次阅读 2016-07-13 18:01:42
    一 . 思路: 1. Android 使用webview加载网页, 在 android 端设置其 userAgent 特定字符 2. 服务器端 php 判断获取的 user agent 中有没有 Android 给的特定字符 ...(这两代码: 找到Android端的userAgent,
  • 情感分析(判断文章正负向)

    千次阅读 2018-09-05 17:50:10
    首先对单条微博进行文本预处理,并以标点符号为分割标志,将单条微博分割为n个句子,...第三步判断是否为感叹,是否为反问,以及是否存在表情符号。如果是,则分句在原有分值的基础上加上或减去对应的权值...
  • OF标记位判断

    千次阅读 2012-06-07 20:05:24
    •计算机硬件判断溢出的方法如下: 最高位有进位但次高位没有进位,或者最高位无进位但次高位有进位;也就是最高位和次高位一个有进位一个无进位。 •我们不是机器不使用这么机械的方法,可以使用如下规则(汇编...
  • 实验7-2-5 判断上三角矩阵 (15 分)

    千次阅读 2018-12-28 18:01:03
    实验7-2-5 判断上三角矩阵 (15 分)  注:此代码与网上其它代码最大区别是利用数组存储判断结果,在读入所有数据后再输出判断结果,而不是逐次输出。  示例: 上三角矩阵指主对角线以下的元素都为0的矩阵...
  • 话.现在理解如下: *of 和 cf 这两个标志寄存器是分开来看的.编译器把数字编译成补码的形式放到内存中  eg: mov al,100 ;补码是64  add al,156 ;补码是9c 在debug 中查看是mov al,64  ...
  • STM32复位类型及判断方法

    千次阅读 2019-07-24 19:44:38
    STM32复位及通过函数判断是何种条件出发的复位 STM32F10xxx支持三种复位形式,分别为系统复位、上电复位和备份区域复位。 一、系统复位: 系统复位将复位所有寄存器至它们的复位状态。 当发生以下任一事件时,...
  • WiFi连接的时候何不知道如判断验证失败的方法,根据网上的资料找到方法接收广播 if (action.equals(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION)) { LogLazy.e("wifi密码错误广播"); int linkWifiResult = ...
  • * 恢复状态以及一些标志位 */ private void reset() { isRecordering = false; mReady = false; //是否触发onLongClick mTime = 0; changeState(STATE_NORMAL); } private boolean wantToCancel(int x, ...
  • 判断一个数是否是素数

    千次阅读 2012-03-27 16:11:31
    判断一个数是否是素数 给定一个整数,判断它是否是素数。由数学知识可得知:只要m能被2,3,…,m-1中的任何一个数整除,那么它就不是素数,否则就是素数。根据这一思路,我们用一个循环过程及判断一个数是否能被整除...
  • 避免把判断处理放入 WHERE 条件

    千次阅读 2006-06-14 19:53:00
    问题描述 业务需求如下: 有表A,在查询的时候,需要根据标志确定是查询大于某个值的记录,还是小于某个值的记录 A、一般的处理方法IF @a = 0 SELECT [TranNumber] FROM A WHERE [TranNumber] 10000ELSE IF @a ...
  • 条件判断语句有3种形式: 1、条件语句为true 时,就执行 处理语句块 If 条件语句 Then 处理语句块 End If 当处理语句块只有一代码的时候,此形式可简化为 If 条件语句 Then 处理语句 例如: Dim age As ...
  • 数据类型判断、转化,对话框(弹框输入、提示,返回文件路径、文件夹),空的一些情况,正则表达式语法,其他常用语句。
  • 我需要写一个存储过程,根据...看了很久旧帖子说要用@@ROWCOUNT判断,但是经过我的测试,发现这种判断并不支持并发的场景,很容易因为其他sql语句的执行导致判断结果发生变化。 跪求大佬们提供支持高并发的判断方法!
  •  (2)if( (byteAscii1 ) || (byteAscii1 > 122) || ((byteAscii1 > 90) && (byteAscii1 ))) 这话是判断该字符是否在a-z 和 A-Z之外,因此我默认的flag是true。  (3)我之前写的是if( (byteAscii1 ) || ...
  • 线性表中数据元素之间的关系是一对一的关系,即除了第一个和最后一个数据元素之外,其它数据元素都是首尾相接的(注意,这话只适用大部分线性表,而不是全部。比如,循环链表逻辑层次上也是一种线性表(存储层次...
  • 目录 任务完成条件:击杀n个敌人,n由关卡设定 游戏结束条件:没血 任务完成的判断依据:击杀目标数 任务完成的标志:方便其他函数和脚本调用 游戏结束代码 任务完成代码 详细代码 任务完成条件:击杀n个敌人,n由...
  • 在刚才的逻辑操作中,可以对变量的值进行逻辑操作,就像和java之类的编程语言一样,最常用的不过if判断,语法如下   if (a >  0) then   select  '> 0';   elseif (a =  0) then   ...
  • 如何判断对方是否喜欢自己的信息经济学解释 作者万星07120775sslaowan@gmail.com指导教师郭春芳 目 录 1 引言... 11.1 一些现象... 11
  • 设计一个循环队列,用front和rear分别作为队头和队尾指针,另外用一个标志tag表示队列是空还是不空,约定当tag为0时队空,当tag为1时队不空,这样就可以用front==rear作为队满的条件要求,设计队列的结构和相关基本...
  •  当然判断完后,我们需要将复位类型的标志置位以防后期出现重复多次判断 void RCC_ClearFlag(void);//清除复位执行函数 1 /** 2 * @brief Clears the RCC reset flags. 3 * @note The reset flags...
  • 在这里判断输赢主要就是判断有没有在横向、纵向、左斜向、右斜向四个方向有五个同一种颜色的棋子连在一起,判断的思路就是扫描二维数组,看在着这个方向上有没有连续的同一个颜色的棋子,如果判断到某一方胜利的话,...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 60,046
精华内容 24,018
关键字:

判断句的标志