栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

C和指针 第5章 操作符和表达式 5.8 问题

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

C和指针 第5章 操作符和表达式 5.8 问题

1.下面这个表达式的类型和值分别是什么?
    (float)(25 / 10); 
#include
#include

int main( void ){
    printf( "sizeof( (float)(25 / 10) ) = %zd, (float)(25 / 10) = %f, "
    "sizeof( float ) = %zdn", sizeof( (float)(25 / 10) ), (float)(25 / 10), sizeof( float ) );

    return EXIT_SUCCESS;
}
 

2.下面这个程序的结果是什么? 
int func( void ){
    static int counter = 1;
    return ++counter;
} 

int main( void ){
    int answer;
    
    answer = func() - func() * func();
    printf( "%dn", answer );
    
    return EXIT_SUCCESS;
}

解析:
这是一个狡猾的问题。比较明显的回答是-10(2 - 3 * 4),但实际上它因编译器而异。乘法运算必须在加法运算之前完成,但并无规则规定函数调用完成的顺序。因此,下面几个答案都是正确的:
-10 (2 - 3 * 4) or (2 - 4 * 3)
-5 (3 - 2 * 4) or (3 - 4 * 2)
-2 (4 - 2 * 3) or (4 - 3 * 2) 
下面是DEV-C++编译器的答案:
#include
#include

int func( void ){
    static int counter = 1;
    return ++counter;
} 

int main( void ){
    int answer;
    
    answer = func() - func() * func();
    printf( "%dn", answer );
    
    return EXIT_SUCCESS;
}

3.位操作符和移位操作符可以用在什么地方? 
解析:
位操作符可以用在让某一位置为1,或者让某一位清零。
移位操作符可以用在进行更快的乘除法,两者结合起来可以用来查看值在内存中的表现形式。 
 

4.条件操作符在运行时比较时较之if语句是更快还是更慢?试着比较下面两个代码段。 
if( a > 3 ){
    i = b + 1;
} else{
    i = c * 5;
}
i = a > 3 ? b + 1 : c * 5;
解析:
不,它们都执行相同的任务。如果你比较吹毛求疵,使用if的哪个方案看上去稍微臃肿一些,因为它具有两条存储到i的指令。但是,它们之间只有一条指令才会执行,所以在速度上并无差别。
#include
#include

int main( void ){
    int a = 5;
    int b = 6;
    int c = 2;
    int i;
    
    if( a > 3 ){
        i = b + 1;
    } else{
        i = c * 5;
    }
    printf( "1:use if statement:i = %d, a = %d, b = %d, c = %dn", i, a, b, c );
    
    i = a > 3 ? b + 1 : c * 5;
    printf( "2:use ?: operator:i = %d, a = %d, b = %d, c = %dn", i, a, b, c );

    return EXIT_SUCCESS;
}

5.可以被4整除的年份是闰年,但是其中能够被100整除的年份又不是闰年。但是,这其中能够被400整除的年份又是闰年。请写一条赋值语句,实现如下功能:如果变量year的值是闰年,把变量leap_year设置为真;如果year的值不是闰年,把leap_year设置为假。 

#include
#include

int main( void ){
    int leap_year = 0;
    int year;
    
    year = 2900;
    if( year % 4 == 0 ){
        leap_year = 1;
    }
    if( year % 4 == 0 && year % 100 == 0 ){
        leap_year = 0;
    }
    if( year % 4 == 0 && year % 100 != 0 ){
        leap_year = 1;
    }
    if( year % 4 == 0 && year % 100 == 0 && year % 400 == 0 ){
        leap_year = 1;
    }
    printf( "method01: %d year is %s year.n", year, leap_year == 1 ? "leap" : " not leap " );
   
    if( year % 400 == 0 ){
        leap_year = 1; 
    } else if( year % 100 == 0 ){
        leap_year = 0;
    } else if( year % 4 == 0 ){
        leap_year = 1;
    } else{
        leap_year = 0;
    }
    printf( "method02: %d year is %s year.n", year, leap_year == 1 ? "leap" : " not leap " );

    return EXIT_SUCCESS;
}

6.哪些操作符具有副作用?它们具有什么副作用? 
解析:
()操作符并无任何副作用,但它所调用的函数可能有副作用。
操作符                副作用
++,--            不论是前缀还是后缀形式,这些操作符都会修改它们的操作数
=                 包括所有其它的复合赋值符:它们都修改作为左值的左操作数
#include
#include

int main( void ){
    int a = 1, b = 1;
    int prefix_a;
    int b_post;
    
    printf( "a = %d, b = %dn", a, b );
    prefix_a = ++a;
    printf( "after prefix_a = ++a, a = %d, prefix_a = %dn", a, prefix_a );
    
    b_post = b++;
    printf( "after b_post = b++, b = %d, b_post = %dn", b, b_post );
    
    return EXIT_SUCCESS;
}

7.下面这个代码段的结果是什么?
int a = 20;
...
if( 1 <= a <= 10 )
      printf( "In rangen" );
else
      printf( "Out of rangen" ); 
#include
#include

int main( void ){
    int a = 20;
    
    if( 1 <= a <= 10 )
        printf( "In rangen" );
    else
        printf( "Out of rangen" ); 

    return EXIT_SUCCESS;
}
 

8.改写下面的代码段,消除多余的代码。
a = f1( x );
b = f2( x + a );
for( c = f3( a, b ); c > 0; c = f3( a, b ) ){
      statements
      a = f1( ++x );
      b = f2( x + a );
} 

解析:
#include
#include

int main( void ){
    for( c = f3( f1( x ), f2( x + a ) ); c > 0; c = f3( f1( ++x ), f2( x + a ) ) ){
        statements;
    }

    return EXIT_SUCCESS;
}

9.下面的循环能够实现它的目的吗? 
解析:
不能实现。因为并不是只有所有的零相加才为零。


 
#include
#include

#define ARRAY_SIZE 4

int main( void ){
    int non_zero = 0;
    int i; 
    int array[ARRAY_SIZE] = { 1, 2, -3, 0 };
    
    printf( "print elements of array:n" );
    for( i = 0; i < ARRAY_SIZE; i += 1 ){
        printf("%d ", array[i] ); 
    } 
    printf( "n" );
    for( i = 0; i < ARRAY_SIZE; i += 1 ){
        non_zero += array[i];
    } 
    if( !non_zero ){
        printf( "Values are all zeron" );
    } else{
        printf( "There are nonzero valuesn" );
    }

    return EXIT_SUCCESS;
}

10.根据下面的变量声明和初始化,计算下列每个表达式的值。如果某个表达式具有副作用(也就是说它修改了一个或多个变量的值), 注明他们。在计算每个表达式时,每个变量所使用的是开始时给出的初始值,而不是前一个表达式的结果。 


#include
#include

int main( void ){
    int a = 10, b = -25;
    int c = 0, d = 3;
    int e = 20;
    printf( "a = %d, b = %d, c = %d, d = %d, e = %dn", a, b, c, d, e ); 
    printf( "a.b = %dn", b );  
    printf( "b.b++ = %dn", b++ );
    printf( "after b++, b = %dn", b );
    b = -25;
    printf( "after b = -25, b = %dn", b );
    printf( "c.--a = %dn", --a );
    printf( "after --a, a = %dn", a );
    a = 10;
    printf( "after a = 10, a = %dn", a );
    printf( "d.a / 6 = %dn", a / 6 );
    printf( "e.a %% 6 = %dn", a % 6 );
    printf( "f.b %% 10 = %dn", b % 10 );
    printf( "g.a << 2 = %dn", a << 2 );  
    
    
    
     
    printf( "h.b >> 3 = %dn", b >> 3 );    
    printf( "i.a > b = %dn", a > b );    
    printf( "j.b = a = %dn", b = a );
    printf( "after b = a, b = %dn", b );
    b = -25;
    printf( "after b = -25, b = %dn", b ); 
    printf( "k.b == a = %dn", b == a );
    printf( "l.a & b = %dn", a & b );
    printf( "m.a ^ b = %dn", a ^ b );
    printf( "n.a | b = %dn", a | b );
    printf( "o.~b = %dn", ~b );
    printf( "p.c && a = %dn", c && a );
    printf( "q.c || a = %dn", c || a );
    printf( "r.b ? a : c = %dn", b ? a : c );
    printf( "s.a += 2 = %dn", a += 2 );
    printf( "after a += 2, a = %dn", a );
    a = 10;
    printf( "after a = 10, a = %dn", a );
    printf( "t.b &= 20 = %dn", b &= 20 );
    printf( "after b &= 20, b = %dn", b );
    b = -25;
    printf( "after b = -25, b = %dn", b );
    printf( "u.b >>= 3 = %dn", b >>= 3 );
    printf( "after b >>= 3, b = %dn", b );
    b = -25;
    printf( "after b = -25, b = %dn", b );
    printf( "v.a %%= 6 = %dn", a %= 6 );
    printf( "after a %% 6, a = %dn", a );
    a = 10;
    printf( "after a = 10, a = %dn", a );
    printf( "w.d = a > b = %d, a > b = %dn", d = a > b, a > b );
    printf( "after d = a > b, d = %dn", d );
    d = 3;
    printf( "after d = 3, d = %dn", d );
    printf( "x.a = b = c = dn", a = b = c = d );
    printf( "after a = b = c = d, a = %d, b = %d, c = %dn", a, b, c );
    a = 10;
    b = -25;
    c = 0;
    printf( "after a = 10, b = -25, c = 0, a = %d, b = %d, c = %dn", a, b, c );
    printf( "y.e = d + (c = a + b) + c = %dn", e = d + (c = a + b) + c );
    printf( "after e = d + (c = a + b) + c, c = %d, e = %dn", c, e );
    c = 0;
    e = 20;
    printf( "after c = 0, e = 20, c = %d, e = %dn", c, e );
    printf( "z.a + b * 3 = %dn", a + b * 3 );
    printf( "aa. b >> a - 4 = %dn", b >> a - 4 );
    printf( "b >> (a - 4) = %dn", b >> (a - 4) );
    printf( "bb.a != b != c = %d, a != b = %d, c = %dn", a != b != c, a != b, c );
    printf( "cc.a == b == c = %d, a == b = %d, c = %dn", a == b == c, a == b, c );
    printf( "dd.d < a < e = %d, d < a = %d, e = %dn", d < a < e, d < a, e );
    printf( "ee.e > a > d = %d, e > a = %d, d = %dn", e > a > d, e > a, d );
    printf( "ff.a - 10 > b + 10 = %d, a - 10 = %d, b + 10 = %dn", a - 10 > b + 10, a - 10, b + 10 );
    printf( "gg.a & 0x1 == b & 0x1 = %d, a = %d, 0x1 == b = %d, a & 0x1 == b = %dn", 
    a & 0x1 == b & 0x1, a, 0x1 == b, a & 0x1 == b ); 
    printf( "a & (0x1 == b) & 0x1 = %d, 0x1 == b = %d, a & (0x1 == b) = %dn", 
    a & (0x1 == b) & 0x1, 0x1 == b, a & (0x1 == b) );
    printf( "hh.a | b << a & b = %d, a = %d, b << a = %d, b = %d, b << a & b = %dn", a | b << a & b, a, b << a,
    b, b << a & b ); 
    printf( "a | ((b << a) & b) = %dn", a | ((b << a) & b) );  
    printf( "ii.a > c || ++a > b = %dn", a > c || ++a > b );
    printf( "after a > c || ++a > b, a > c = %d, a = %dn", a > c, a );
    printf( "jj.a > c && ++a > b = %dn", a > c && ++a > b );
    printf( "after a > c && ++a > b, a = %d, a > b = %dn", a, a > b );
    a = 10;
    printf( "after a = 10, a = %dn", a );
    printf( "kk.!~b++ = %dn", !~b++ );
    printf( "after !~b++, b = %dn", b );
    b = --b;
    printf( "after b = --b, b = %dn", b );
    printf( "b = %d, ~b = %d, !~b = %dn", b, ~b, !~b );
    b = -25;
    printf( "after b = -25; b = %dn", b );
    printf( "ll.b++ & a <= 30 = %d, a = %d, a <= 30 = %dn", b++ & a <= 30, a, a <= 30 );
    printf( "after b++ & a <= 30, b = %dn", b );
    b = --b;
    printf( "after b = --b, b = %dn", b );
    printf( "b & a <= 30 = %d, a = %d, a <= 30 =%dn", b && a <= 30, a, a <= 30 );
    b = -25;
    printf( "after b = -25, b = %dn", b );
    printf( "mm.a - b, c += d, e - c = %d, a = %d, b = %d, d = %d, e = %dn", (a - b, c += d, e - c), a, b, d, e );
    printf( "after a - b, c += d, e - c, c = %dn", c );
    c = 0;
    printf( "after c = 0; c = %dn", c );
    printf( "nn.a <<= 3 > 0 = %d, 3 > 0 = %dn", a <<= 3 > 0, 3 > 0 );
    printf( "after a <<= 3 > 0, a = %dn", a );
    a = 10;
    printf( "after a = 10, a = %dn", a );
    printf( "a << (3 > 0) = %dn", a << (3 > 0) );
    printf( "oo.a <<= d > 20 ? b && c++ : d-- = %dn", a <<= d > 20 ? b && c++ : d-- ); 
    printf( "after a <<= d > 20 ? b && c++ : d--, d = %d, d > 20 = %d, a = %dn", d, d > 20, a );

    return EXIT_SUCCESS;
}

11.下面列出了几个表达式。请判断编译器是如何对各个表达式进行求值的,并在不改变求值顺序的情况下,尽可能去除多余的括号。 
#include
#include

int main( void ){
    int a = 1, b = 6, c = 2;
    
    printf( "a.a + (b / c) = %dn", a + (b / c) );
    printf( "a + b / c = %dnn", a + b / c );
    
    printf( "b.(a + b) / c = %dnn", (a + b) / c );
    
    printf( "c.(a * b) %% 6 = %dn", (a * b) % 6); 
    printf( "c.a * b %% 6 = %dnn", a * b % 6); 
    
    printf( "d.a * (b %% 6) = %dnn", a * (b % 6) );
    
    printf( "e.(a + b) == 6 = %dn", (a + b) == 6 );
    printf( "a + b == 6 = %dnn", a + b == 6 );
    
    printf( "f.!((a >= '0') && (a <= '9')) = %dn", !((a >= '0') && (a <= '9')) );
    printf( "!(a >= '0' && a <= '9') = %dnn", !(a >= '0' && a <= '9') );
    
    printf( "g.((a & 0x2f) == (b | 1)) && ((~c) > 0) = %dn", ((a & 0x2f) == (b | 1)) && ((~c) > 0) );
    printf( "(a & 0x2f) == (b | 1) && ~c > 0 = %dnn", (a & 0x2f) == (b | 1) && ~c > 0 ); 
    
    printf( "h.((a << b) - 3) < (b << (a + 3)) = %dn", ((a << b) - 3) < (b << (a + 3)) );
    printf( "(a << b) - 3 < b << a + 3 = %dnn", (a << b) - 3 < b << a + 3 );
    
    printf( "i.~(a++) = %dn", ~(a++) );
    a = 1;
    printf( "~a++ = %dnn", ~a++ );
    
    printf( "j.((a==2) || (a == 4)) && ((b == 2) || (b == 4)) = %dn", ((a==2) || (a == 4)) && ((b == 2) || (b == 4)) );
    printf( "(a==2 || a == 4) && (b == 2 || b == 4) = %dnn", (a==2 || a == 4) && (b == 2 || b == 4) );
    
    printf( "k.(a & b) ^ (a | b) = %dn", (a & b) ^ (a | b) );
    printf( "a & b ^ (a | b) = %dnn", a & b ^ (a | b) );
    
    printf( "l.(a + (b + c)) = %dn", (a + (b + c)) );
    printf( "a + b + c = %dnn", a + b + c );
    
    return EXIT_SUCCESS;
}

12.在你的机器上对一个有符号值进行右移位操作时,如何判断执行的是算术移位还是逻辑移位? 

解析:

通过查看内存中位的分布来判断进行算术移位还是逻辑移位。


#include
#include
#include

int main( void ){
    int si;
    int si2; 
    int bit_of_int;
    int i;
    
    si = -5;
    bit_of_int = sizeof(int) * CHAR_BIT;
    
    printf( "si = %dn", si );
    printf( "print the bit of number %d in binary system:n", si );
    for( i = bit_of_int - 1; i >= 0; --i ){
        printf( "%c", si & (1u << i) ? '1' : '0' );    
    }
    printf( "n" );
    
    si2 = si >> 1;
    printf( "after si2 = si >> 1, si2 = %d, print the bit of number %d in binary system:n", si2, si2 );
    for( i = bit_of_int - 1; i >= 0; --i ){
        printf( "%c", si2 & (1u << i) ? '1' : '0' );    
    }
    printf( "n" );
    
    return EXIT_SUCCESS;
}

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/977382.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号