c第四天

第四课    进制转换与运算符
一、十进制与二进制
十进制:逢十进一
二进制:逢二进一
0        0
1        1
2      10
3      11
4    100
5    101
6    110
7    111
8  1000
9  1001
二、进制转换
1.二进制与十进制的转换
1)位与权
93 = 9 * 10 + 3 * 1
         位  权     位   权
整数93在一个字节中的二进制形式:
0     1   0   1   1 1 0 1 - 位
128 64 32 16 8 4 2 1 - 权
2)零和正数:符号位(最高位)为0
A.二转十:一位加权,零位不见
01011101=64+16+8+4+1=93
01101101=64+32+8+4+1=109
B.十转二:有权添一,无权补零
93-64=29-16=13-8=5-4=1 -> 01011101
109-64=45-32=13-8=5-4=1 -> 01101101
127-64=63-32=31-16=15-8=7-4=3-2=1 -> 01111111
3)负数:符号位(最高位)为1
A.二转十:取反加一,转十添负
10100011取反01011100加一01011101转十
64+16+8+4+1=93添负-93
10010011取反01101100加一01101101转十
64+32+8+4+1=109添负-109
B.十转二:去负转二,取反加一
-93去负93转二93-64=29-16=13-8=5-4=1->01011101取反10100010加一10100011
-109去负109转二109-64=45-32=13-8=5-4=1->01101101取反10010010加一10010011
练习:
char c = -191;
printf ("%d", c); // 65
printf ("%c", c); // A
-191去负191转二191-128=63-32=31-16=15-8=7-4=3-2=1->10111111取反01000000加一01000001=64+1=65
-------------------------------------------
short h = -191;
printf ("%h", h); // -191
-191去负191转二
0000000010111111取反
1111111101000000加一
1111111101000001 -> -191
2.二进制和十六进制的转换
四位二进制对应一位十六进制
十进制       二进制       十六进制
0                0000         0
1                0001         1
2                0010         2
3                0011         3
4                0100         4
5                0101         5
6                0110         6
7                0111         7
8                1000         8
9                1001         9
10              1010         A
11              1011         B
12              1100         C
13              1101         D
14              1110         E
15              1111         F
一个字节对应两位十六进制
93              0101 1101             0x5D
109            0110 1101             0x6D
-93             1010 0011             0xA3
-109           1001 0011             0x93
-191 1111 1111 0100 0001    0xFF41
3.二进制和八进制的转换
三位二进制对应一位八进制
十进制        二进制        八进制
0                 000           0
1                 001           1
2                 010           2
3                 011           3
4                 100           4
5                 101           5
6                 110           6
7                 111           7


93               01 011 101             0135
109             01 101 101             0155
-93
-109
-191
三、运算符与表达式
1.算数运算
1)+、-、*
2)/、%
整数相除,取整数部分。
/和%不能对整数0进行操作,否则会中断程序。但是可以对浮点0进行操作,但是得到的结果是inf,表示无穷大。
%不能对浮点数使用。
/向零取整(取更接近0的数字)。
%的结果与其左操作数的符号一致。
练习:要求用户输入一个秒数,以xx小时xx分钟xx秒的格式打印出来。
2.赋值运算
1)将赋值运算符右边的值付给左边的变量。
int a;
a = 10; // 将10赋给a
2)赋值表达式的值就是赋值表达式左操作数的值。
int a, b, c;
a = b = c = 10; // a = (b = (c = 10));
printf ("%d,%d,%d\n", a, b, c); // 10,10,10
3)赋值运算符的左操作数必须是一个左值——可被赋值的对象——变量,常量或表达式不能被赋值。
100 = 200; // error
100 = a; // error
a + b = c; // error
4)赋值运算符是“=”而不是“==”。
5)赋值运算符还可和其它运算符结合起来使用,构成复合赋值。
a += b; // a = a + b
a %= b; // a = a % b
6)初始化与赋值是不同的。
int a = 10; // 初始化
a = 20; // 赋值
3.自增减运算
1)++/--:变量自增/减1。
int a = 10;
a++; // a:11
a--; // a:10
++a; // a:11
--a; // a:10
2)不能用于常量。
100++; // error
--100; // error
3)可以用于所有的整型类变量,以及浮点类,但是多数情况下用于int。
4)前后缀自增减的区别:
前缀:先自增减,在计算表达式。
后缀:先计算表达式,再自增减。
a++表达式和++a表达式的值都是从操作数a的内存空间中得到的。二者的区别在于,一个是先取表达式的值再自增,另一个是先自增在取表达式的值。
5)忠告:自增减运算最好不要在一个表达式中使用多次。
4.关系运算
>/>=/</<=/==/!=
关系运算表达式的值是整数:1或者0。
逻辑真:1
逻辑假:0
5.逻辑运算
1)逻辑与(&&)、逻辑或(||)、逻辑非(!)
A && B:只有当A和B的值都为真(非零)时,表达式的值才为真。
A || B:只有当A和B的值都为假(零)时,表达式的值才为假。
! A:当A的值为真时,表达式的值为假,当A为假时,表达式的值为真。
2)短路运算
A && B:如果A的值为假,则B不处理。
A || B:如果A的值为真,则B不处理。
6.位运算
1)位与(&)/位或(|)/位异或(^)/位反(~)
位与:参与运算的两位都是1结果为1,否则为0。位与可以置某一位为0,也可以得到某一位的值。
    10110001 A
    11101111 B
&)-----------
    10100001 C
          ^
    10110001 A
    00010000 B
&)----------- 若A&B==B,则A中此位为1
    00010000 C
          ^
位或:参与运算的两位都是0结果为0,否则为1。位或可以置某一位为1,也可以得到某一位的值。
    10100001 A
    00010000 B
|)------------
    10110001 C
          ^
    10100001 A
    11101111 B
|)------------ 若A|B==B,则A中此位为0
    11101111
          ^
异或:参与运算的两位相异为1,相同为0。异或可以翻转某一位,想翻哪位哪位就是1,其余为0。
    10101010 A
    00100100 B
^)------------
    10001110 C
        ^    ^
A^B->C
C^B->A
C^A->B
异或还可用于在不增加第三变量的前提下,交换两个变量的值。
int a = 10, b = 20;
int c = a;
a = b;
b = c;
--------------------
a : 1011
b : 0110
a = a ^ b; // a : 1101
b = a ^ b; // b : 1011
a = a ^ b; // a : 0110
位反:按位取反
    01100001
~)-----------
    10011110
2)左右移位
A.有符号数:左移补零,右移补符
10101010 << 1 -> 01010100
-86                           84
10101010 >> 1 -> 11010101
-86                           -43
B.无符号数:左移右移全补零
10101010 << 1 -> 01010100
170                          84
10101010 >> 1 -> 01010101
170                          85
在不发生溢出的情况下,左移一位即乘2,右移一位即除2。
00000001 << 1 -> 00000010
1                               2
7.取地址和解引用(取目标)运算
取地址&:获取一个变量的地址,即其首字节的地址。
解引用*:根据地址获得变量的值。
8.类型转换
1)类型升级:由低级类型转换为高级类型。浮点高于整型,长整型高于短整型(long long > long > int > short > char)。若有符号类型能够表示无符号类型的值,则取有符号类型,否则按无符号处理。
2)强制转换:目标类型变量 = (目标类型)源类型变量。
double f = 1.23;
int n = (int)f; // n : 1
无论哪种形式的类型转换对于源变量都不会产生任何影响。
9.条件运算
条件表达式 ? 表达式1 : 表达式2

若条件表达式为真,则整个表达式的值取表达式1的值,否则整个表达式的值取表达式2的值。

#include <stdio.h>
int main (void) {
    int a = 10;
    printf ("%d\n", ++a); // 11
    printf ("%d\n", a); // 11
    a = 10;
    printf ("%d\n", a++); // 10
    printf ("%d\n", a); // 11
    a = 10;
    printf ("%d\n", a++ + ++a); //22, 11+11
    printf ("%d\n", a); //12
    a = 10;
    printf ("%d\n", a++ + ++a + ++a);
 // 34,11+11+12
    printf ("%d\n", a); // 13
    a = 10;
    printf ("%d\n", a++ + --a - a-- * ++a); // 9+9-10*10=-82
    printf ("%d\n", a); // 10
    return 0;
}

#include <stdio.h>
int main (void) {
    int a, b, c;
    a = 100;
    printf ("a=%d\n", a);
    a = b = c = 200;
    printf ("%d,%d,%d\n", a, b, c);
    //(a = b) = 300; // 表达式不能做左值
    //a + b = c;
    a += b;
    printf ("a=%d\n", a);
    return 0;
}

#include <stdio.h>
int main (void) {
    int a = 2, b = 3, c = 0;
    printf ("a/b=%d\n", a / b);
    printf ("a%%b=%d\n", a % b);
    //printf ("a/c=%d\n", a / c);
    //printf ("a%%c=%d\n", a % c);
    double d = 0;
    printf ("a/d=%lf\n", a / d);
    //printf ("a%%d=%lf\n", a % d);
    printf ("%d,%d\n", 7/3, -7/3);
    printf ("%d,%d\n", -7%3, 7%-3);
    return 0;
}

#include <stdio.h>
int main (void) {
    printf ("请输入一个秒数:");
    int sec;
    scanf ("%d", &sec);
    printf ("%d小时%d分钟%d秒\n", sec / 3600, sec % 3600 / 60, sec % 60);
    return 0;
}

#include <stdio.h>
int main (void) {
    printf ("%d\n", 5>3 && 5<8); // 1
    printf ("%d\n", 5>3 && 5>8); // 0
    printf ("%d\n", 5<3 && 5<8); // 0
    printf ("%d\n", 5<3 && 5>8); // 0
    printf ("%d\n", 10 || 0); // 1
    int a = 0;
    printf ("%d\n", a++ || a++); // 1
    printf ("%d\n", ! (10 > 20)); // 1
    printf ("%d\n", ! 10 > 20); // 0
    a = 10;
    printf ("%d\n", 5>3 && (a=100));
    printf ("%d\n", a); // 100
    printf ("%d\n", 5<3 && (a=200));
    printf ("%d\n", a); // 100
    printf ("%d\n", 5>3 || (a=300));
    printf ("%d\n", a); // 100
    int b, c;
    a = b = c = 1;
    ++a || --b && ++c;
    // 等价++a || (--b && ++c)
    printf ("%d,%d,%d\n", a, b, c);
    // 2,1,1
    return 0;
}

#include <stdio.h>
int main (void) {
    printf ("%d\n", 5 > 2);
    printf ("%d\n", 3 <= 3);
    printf ("%d\n", 10 == 8);
    printf ("%d\n", 10 != 10);
    return 0;
}

#include <stdio.h>
int main (void) {
    int a = ((10 > 5) ? 10 : 5);
    printf ("%d\n", a);
    a = ((10 < 5) ? 10 : 5);
    printf ("%d\n", a);
    a = 10;
    int b = 9;
    int c;
    c = (--a == b++) ? --a : b++;
    printf ("%d,%d,%d\n", a, b, c);
    // 8,10,8 
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值