1 三目运算符

  • 三目运算符(a?b:c)可以作为逻辑运算的载体
  • 规则: 当a为真时,返回b,否则返回c的值

如下面的代码:

#include <stdio.h>

int main()
{
    int a = 1;
    int b = 2;
    int c = 0;
    
    c = a < b ? a : b;
    
    //(a < b ? a : b) = 3;
    
    printf("%d\n", a);
    printf("%d\n", b);
    printf("%d\n", c);
    
    return 0;
}
  • 运行结果为:

1
2
1

  • 上面的代码中,第11行给注释掉了。这行代码写的有问题。

  • 因为三目运算符是返回变量的值,而不是变量本身,所以11行中,左操作符是返回的一个具体的值,对这个值再赋值,肯定是错误的。(虽然它返回的是一个具体的数字,但是这个数字也是有数据类型的,具体是什么类型,下面会讲。)

(a?b:c),如果b与c的类型不一样,返回值应该是什么类型?

  • 通过隐式类型转换规则,返回较高类型
  • 当b和c不能隐式转换为同一类型时,编译将会出错

比如在下图中的三个三目运算符中,第三个printf中的double类型和 *p 指针类型不能转换,将会编译期间报错。

1.1 三目运算符的返回类型的代码案例分析

  • 代码:18-2.c
#include <stdio.h>

int main()
{   
    char c = 0;
    short s = 0;
    int i = 0;
    double d = 0;
    char* p = "str";
        
    printf( "%d\n", sizeof(c ? c : s) );
    printf( "%d\n", sizeof(i ? i : d) );
    printf( "%d\n", sizeof(d ? d : p) );

    return 0;
}
  • 使用gcc 4.4.5 编译程序显示如下错误:

  • 将第13行注释掉编译运行结果如下:

  • 第一个为什么是4。实际上是因为第一个返回了int类型。具体类型转换的规则参考C语言中的类型转化

2 逗号表达式

在C语言中:

  • 逗号表达式是C预压的一种“粘结剂”
  • 逗号表达式用于将多个子表达式连接为一个表达式
  • 逗号表达式的值为最后一个子表达式的值
  • 逗号表达式的前N-1个子表达式可以没有返回值,最后一个子表达式有返回值即可
  • 逗号表达式按照从左向右的顺序计算每个表达式的值

2.1 逗号表达式代码案例分析

  • 代码 18-3.c
#include <stdio.h>

void hello(){
    printf("Hello!\n");
}
int main(){
    
    int a[3][3]={
        (0,1,2),
        (3,4,5),
        (6,7,8)
    };
    
    int i = 0;
    int j = 0;
    
    while(i < 5)
        printf("i = %d\n", i),
    
    hello(),
    
    i++;
    
    for(i=0;i<3;++i){
        for(j=0;j<3;++j){
            printf("a[%d][%d] = %d\n", i,j,a[i][j]);
        }
    }
    
    return 0;
}
  • 上述代码编译运行结果为:

  • 第一个while循环后的三个语句,都是逗号表达式的一员,所以while循环5次
  • 定义数组a的时候,由于是使用的圆括号,里面的定义也是三个逗号表达式。应该改成下面的定义:
int a[3][3]={
        {0,1,2},
        {3,4,5},
        {6,7,8}
    };

那么结果就是正确的。注意逗号表达式的使用。

2.2 如何用一行代码实现 strlen函数

  • 代码 18-4.c
#include <stdio.h>
#include <assert.h>

int strlen(const char* s){
    return assert(s),(*s ? strlen(s+1)+1 : 0);
}
int main(){

    printf("len = %d\n", strlen("Delphi"));

    printf("len = %d\n", strlen(NULL));
    return 0;
}
  • 编译运行结果如下:

  • 是不是体会到了逗号表达式与三目运算符的妙用?

3 总结

  • 三目运算符返回变量值,而不是变量本身
  • 三目运算符通过隐式类型转换的规则确定的返回值的类型
  • 逗号表达式按照从左向右的顺序计算每个子表达式的值
  • 逗号表达式的值为最后一个子表达式的值