解剖C语言---数据类型转换与数据运算集锦

C语言学习笔记

      之  数据类型转换与数据运算

一:数据类型转换

1自动转换(5+5.000000=?结果是10还是10.000000):发生在不同类型的数据混合运算时,由编译系统自动完成。

不同的数据类型,要转换成精度较高的。


A转换按数据长度增加的方向进行,确保精度不降低,比如:int型和long型运算时,先把int量转成long型后再进行运算

  BCharshort类型要转换成int ,然后再参加运算。

 C在赋值运算中,赋值号两边的数据类型不同时,赋值号右边的类型将转换为左边的类型,如果右边的数据类型长度比左边长,将丢失一部分,丢失的部分按四舍五入向前舍入。

比如:计算10+a+5*5.000000 105为整型,5.000000 为双精度实型)

    先计算‘a’的整型为97+10=107//char转换为int 

      计算5*5.000000=25.000000//将整型5转换为double型实型

      计算107+25.000000=132.000000; //将整型107转换为double型;

所以它的最终结果为精度最高的double型。

比如我们来看两个程序实例


1
2
3
4
5
6
7
8
9
//#include <stdio.h>
# include  <iostream>
using  namespace  std;
void  main()
{
    unsigned  int  a= 6 //定义无符号整型
    int  b=- 20 //定义有符号整型
    cout<<a+b<<endl; //输出a+b的值,类型随a+b值的类型而定
}



1
2
3
4
5
6
7
8
9
//#include <stdio.h>
# include  <iostream>
using  namespace  std;
void  main()
{
    unsigned char a= 6 //定义无符号整型
    char b=- 20 //定义有符号整型
    cout<<a+b<<endl; //输出a+b的值,类型随a+b值的类型而定
}


为什么是一串很大的整数呢?而不是-14呢?问题就在自动转换上,我们观察上述讲过的转换规则,unsignedint同时出现运算时,int需要转换成unsigned,即:有符号需要转换成无符号类型。程序中的-20需要转换成无符号整型。

2)强制类型转换int型修改为char类型之后,结果竟然是-14,这又是为什么呢?还是自动转换规则。看规则, int以下类型(short,char不管有无unsigned)计算会转为int,也就是说不管有没有符号,char类型都要转换成int ,所以a+b遵循了有符号整型的运算。

区别与自动转换,强制转换很明显是强制的。格式为:(类型说明符)表达式

      比如:int a ; (float) a 的意思是将整型强制转换为了实型。(int)(x+y)的意思是将x+y的值转换为整型。

3)需要注意的是:无论是自动转换或者是强制转换,都只是为本次运算的需要而对变量的数据长度进行的临时性转换,而不改变数据说明时对该变量定义的类型

    如下程序:


1
2
3
4
5
6
# include  <stdio.h>
main()
{
    float f= 5.75 ;
    printf( "(int)f=%d\nf=%f\n" ,( int )f,f);
}




1.
运算符的优先级与结合性           二:数据运算

优先级

结合性

运算符

备注

1

左结合

()
[]
->
.

圆括号
下标运算符
指向结构体成员运算符
结构体成员运算符

2

右结合

!
~
++
--
+
-
(类型)
*
&
sizeof

逻辑非运算符
按位取反运算符
前缀增量运算符
前缀减量运算符
正号运算符
负号运算符
类型转换运算符
指针运算符
地址运算符
长度运算符

3

左结合

*
/
%

乘法运算符
除法运算符
取余运算符

4

左结合

+
-

加法运算符
减法运算符

5

左结合

<<
>>

左移运算符
右移运算符

6

左结合

<
<=
>
>=

关系运算符

7

左结合

==
!=

等于运算符
不等于运算符

8

左结合

&

按位与运算符

9

左结合

^

按位异或运算符

10

结合性

|

按位或运算符

11

左结合

&&

逻辑与运算符

12

左结合

||

逻辑或运算符

13

右结合

? :

条件运算符

14

右结合

=
+=
-=
*=
/=
%=
&=
^=
|=
<<=
>>=

赋值运算符

15

左结合

,

逗号运算符

2.算术运算(+-*/%

1乘除取余的优先级要高于加减;

2/”除运算,参加除运算的变量均为整数,结果也为整数(舍去小数),多数机器上采取“向零取整”的原则。比如:7/4=1(而不是1.75)-7/4=-1

3%,参与模运算的变量必须都为整型,其结果为两数相除的余数,并且余数与被除数的符号相同。比如:7%4=3,  -8%5=-3,   8%-5=3  

3.赋值运算

1变量名=表达式,运算顺序是从右向左。比如:x=y=z=0, x=(y=(z=0))

(2)当赋值运算符两边的数据类型不同时,系统将自动进行类型转换,赋值运算符右边的数据类型转换成左边的变量类型,在上一篇中已经说过了。

3复合赋值运算:比如:n+=1等价于n=n+1; x*=y+1等价于x=x*(y+1)

4.自增自减运算

如果n=3 ,n的值和m的值如下表所示


n的值

m的值

运算分解

m=n++

4

3

m=n; n=n+1

m=++n

4

4

n=n+1; m=n

m=-n++

4

-3

m=-n; n=n+1

m=- ++n

4

-4

n=n+1 ;m=-n;


关于自增自减是一个重要的概念,在之后的指针学习中还会重点学习。

5.逗号运算

1表达式1,表达式2....表达式n。自左向右结合。

2表达式n的值为整个逗号表达式的值。比如:a=(1,2,3,4,5,6),a的值等于6。也就是最后一个的值。

3逗号运算符在所有运算符中的优先级别最低,它往往起到了把若干个表达式串联起来的作用。比如:a=3*4,a*5,a+10。 从左向右 先去3*4,然后将12的值赋给a,然后计算a*5。将60的值赋给a,然后计算a+10的值。

6.关系运算与逻辑运算

关系运算无非就是大于(>)小于(<),逻辑运算有非(!)与(&&)或(||

逻辑表达式的值只有真(1)和假(0)两个值

A的取值

B的取值

A(求反)

A&&B

A||B

0

0

0

1

1

0

0

0

0

1

0

1

0

1

0

0

1

0

0

对于关系运算来说,a>b>c并不代表着a的值比b大,b的值比a大。关系运算与逻辑运算需要密切合作。我们来举一个例子:看两个程序。


1
2
3
4
5
6
7
8
9
10
11
12
# include  <stdio.h>
main()
{
    int  a= 6 ,b= 4 ,c= 1 ;
    if (a>b>c)
    {
        printf( "OK\n" );
    }
    else {
        printf( "ERROR\n" );
    }
}


我们看到的结果竟然是 ERROR ,而不是我们预想的 OK ,这是为什么呢?原因就在判断上。 在数学上,a>b>c一点都没有错,但是在我们的C程序中,计算机判断条件的依据只有两种结果,那就是1(真)或者是0(假)。比如:a>b是真,所以a>b的值为1,然后1>c吗?很显然1=c,所以if()条件中的条件并不成立,所以结果为ERROR 那这样怎么改呢?很简单,用逻辑运算符


1
2
3
4
5
6
7
8
9
10
11
12
13
# include  <stdio.h>
main()
{
    int  a= 6 ,b= 4 ,c= 1 ;
    //if(a>b>c)
    if (a>b && b>c)
    {
        printf( "OK\n" );
    }
    else {
        printf( "ERROR\n" );
    }
}




7.1:位运算之取反(~)

1取反能对一个二进制的每一位都取反。

 看一个程序实例:


1
2
3
4
5
6
7
8
9
# include  <stdio.h>
main()
{
     unsigned char a,b; //定义无符号
//char a,b;
a= 26 ;
b=~a; //对a取反
    printf( "b=%u\n" ,b); //以无符号输出
}




分析一下char类型默认分配一个字节,即8位。26的二进制为:00011010

  对26的二进制取反(~a)得:11100101,我们在深入剖析类型修饰符unsigned中讲解过,无符号的二进制最高位为数据位,所以11100101的十进制为229

2为了便于区分有符号和无符号的区别,我们再来做一个程序实例:


1
2
3
4
5
6
7
8
9
10
# include  <stdio.h>
main()
{
     //unsigned char a,b;//定义无符号
char a,b; //定义有符号
a= 26 ;
b=~a; //对a取反
     //printf("b=%u\n",b);//以无符号输出
     printf( "b=%d\n" ,b); //以有符号输出
}


26 的二进制: 00011010 ,取反: 11100101 char 类型默认有符号(我的是有符号,有些课本中说无符号),所以最高位为符号位,所以是负数,对 11100101 减一取反是: 10011011 ,转换成二进制为 -27  

  对于这一块不理解的同学可以参考:C语言进阶[暑期特别篇]深入剖析类型修饰符unsigned

7.2:位运算之左移(<<

左移是将一个数的各个二进制位全部向左平移若干位,左边移出的部分忽略,右边空出的位置补0,比如:

      A = 0 0 0 1 1 0 1 0

A<<2=0 1 1 0 1 0 0 0

 一个数据,每左移一位相当于乘以2,左移2位相当于乘以4。比如:4左移2=4*4=16

7.3 位运算之右移(>>

右移是将一个数的各个二进制位全部向右平移若干位,右边移出的部分忽略,左边空出的位置对于无符号数补0,对于有符号数,若原符号位为0,则全补0,若原符号位为1,则全补1比如:

   A 被定义为unsigned(无符号) char

            A= 1 0 0 1 1 0 1 0

        A>>2 = 0 0 1 0 0 1 1 0

A被定义为char (默认有符号)

           A= 1 0 0 1 1 0 1 0

       A>>2 = 1 1 1 0 0 1 1 0

7.4 位运算之与或(&&|)

比如: a= 1 0 1 1 1 0 1 0

         b= 0 1 1 0 1 1 1 0

     a&&b= 0 0 1 0 1 0 1 0  只有111,其它的全是0

       a|b= 1 1 1 1 1 1 1 0  只要有一个1,就是1

7.5 位运算之异或(^

异或运算的作用是判断两个相应位的值是否相异。相异为1,反之则为0

         a= 1 0 1 1 1 0 1 0

         b= 0 1 1 0 1 1 1 0

       a^b= 1 1 0 1 0 1 0 0


发布了4 篇原创文章 · 获赞 1 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/HughNian/article/details/20122045