指引网

当前位置: 主页 > 编程开发 > C >

C语言中 整数, 浮点, 逻辑, 类型转换和条件运算 总结教程

来源:网络 作者:佚名 点击: 时间:2017-07-19 23:08
[摘要]  本文是我们总结的C语言进阶教程,数据类型 整数, 浮点, 逻辑, 类型转换和条件运算,本教程给出了很多代码实例,比较实用。

【C语言的类型】

整数:

char, short, int, long, long long

浮点数:

float,double,long double

逻辑:

bool:通过头文件定义

指针

 

自定义类型

 

【类型有什么不同】

类型名称:int,long,double

输入输出时的格式化:%d,%ld,%lf

所表达的数的范围:char < short < int < float < double

内存中所占据的大小:1个字节到16个字节,使用sizeof()得到大小,sizeof是静态运算符,它的结果在编译时刻就决定了,sizeof的运算不会计算。

内存中的表达形式:二进制数(补码),编码

 

【整数类型】

//  main.c
//  Created by weichen on 15/3/25.
//  Copyright (c) 2015年 weichen. All rights reserved.
#include <stdio.h>

int main(int argc, const char * argv[]) {
    printf("sizeof(char)=%ld\n", sizeof(char));         //1 字节(8bite)
    printf("sizeof(short)=%ld\n", sizeof(short));       //2 字节
    printf("sizeof(int)=%ld\n", sizeof(int));           //4 取决于编译器(cpu),通常的意义是“1个字”
    printf("sizeof(long)=%ld\n", sizeof(long));         //8 取决于编译器(cpu),通常的意义是“1个字”
    printf("sizeof(long long)=%ld\n", sizeof(long long));//8 8字节

    //gcc ./test.c -o -m32  #以32平台架构编译显示
    
    
    char c = 255;
    int i = 255;
    printf("c=%d, i=%d\n", c, i); //c=-1, d=255
    
    unsigned char d = 255;        //用来表示整数不以补码的形式表示,看做纯二进制
    printf("d=%d\n", d);          //d=255
    
    char e = 127;
    e = e + 1;
    printf("e=%d\n", e);          //-128
    
    unsigned char f = 127;
    f = f + 1;
    printf("f=%d\n", f);          //128
    
    return 0;
}

//int 是用来表达寄存器的
/*
 计算机以二进制表达正整数,表达负数用补码:
 ->  00000000
 ->  00000001
+ 00000001 -> 1000000000 \
                                      |
- 00000001 -> (负1)     |
                                      |
 (1)00000000 - 00000001 -> 11111111   /

   ① 11111111被当做纯二进制时,是255,被当作补码时,是-1
   ② 同样,对于-a,实际是(2^n - 1),n是这种类型的位数;补码是0-a
   ③ 补码的意思是拿补码和原码可以加出一个溢出的“零”
*/


//数的范围
/*
 一个字节(8位),表达的是:
- 11111111

 其中,00000000 -> 0
~ 10000000 -> -1 ~ -128   //用补码表示
~ 01111111 -> 1 ~ 127          //纯二进制表示
*/

//unsigned
/*
 如果一个字面量常数想要表达自己是unsigned,可以在后面加u或U
    255U
 用l或L表示long(long)
 unsigned的初衷并非扩展数能表达的范围,而是为了做纯二进制运算,主要是为了移位。
 */

//整数越界
/*
 整数是以纯二进制方式进行计算的,所以:
+ 1 -> 100000000 -> 0
+ 1 -> 10000000  -> -128
- 1 -> 01111111  -> 127
 */

//整数的输入输出
/*
 只有两种形式:int或long long
 %d:int
 %u:unsigned
 %ld:long long
 %lu:unsigned long long
 */

//8进制和16进制
/*
 一个以0开始的数字字面量是8进制
 一个以0x开始的数字字面量是16进制
 %o用于8进制,%x用于16进制
 8进制和16进制只是如何把数字表达为字符串,与内部如何表达数字无关
 
 16进制很适合表达二进制数据,因为4位二进制正好是一个16进制位
 8进制的一位数字正好表达3位二进制
    因为早期计算机的字长是12的倍数,而非8
 */

//选择整数类型
/*
 为什么整数要有那么多种?
    为了准确表达内存,做底层程序的需要
 没有特殊需要,就选择int
    现在的CPU的字长普遍是32位或64位,一次内存读写就是一个int,一次计算也是一个int,选择更短的类型不会更快,甚至可能更慢
    现代的编译器一般会涉及内存对齐,所以更短的类型实际在内存中有可能也占据一个int的大小(虽然sizeof告诉你更小)
 unsigned与否只是输出的不同,内部计算是一样的,所以现代高级语言大多已不区分非负。
 */

 【浮点类型】

//  main.c  
//  Created by weichen on 15/4/6.
//  Copyright (c) 2015年 weichen. All rights reserved.
#include <stdio.h>

int main(int argc, const char * argv[]) {
    // 浮点类型
    /*
     类型     字长      范围                                                      有效数字
     float    32   ±(1.20*10^-38 ~ 3.40*10^38), 0, ±inf(无穷大), nan(非数字)       7(准确的位数)
     double   64   ±(2.2*10^-308 ~ 1.79*10^308),0, ±inf, nan                     15
     
     类型     scanf     printf
     float     %f       %f,%e(科学计数法)
     double    %lf      %f,%e
     */
    
    double ff = 12.345;
    printf("%e, %f\n", ff, ff);     //1.234500e+01, 12.34500
    printf("%E\n", ff);             //1.234500E+01
    
    //在%和f之间加上.n可以指定输出小数点后几位,这样的输出是做四舍五入的
    printf("%.3f\n", -0.0049);      //-0,005    小数点后保留三位
    printf("%.30f\n", -0.0049);     //-0.004899999999999999841793218991
    printf("%.3f\n", -0.00049);     //0.000
    
    printf("%f\n", 1.0/0.0);        //inf
    printf("%f\n", -1.0/0.0);       //-inf
    printf("%f\n", 0.0/0/0);        //nan
    //printf("%d\n", 12/0);           //无法编译通过,无穷大无法用整数表达,可以用浮点数表达
    
    float a, b, c;
    a = 1.34f;
    b = 1.22f;
    c = a + b;
    if( c == 2.56) {
        printf("a = b\n");
    } else {
        printf("a != b, c=%.10f 或 %f\n", c, c); //a != b, c=2.5599999428 或 2.560000(七位有效数字四舍五入而来)
    }
    
    //浮点运算的精度
    /*
     带小数点的字面量是double而非float
     float需要用f或F后缀来表明身份
     float1 == float2 可能失败
     fabs(f1-f2) < 1e^-12   #计算绝对值与最小误差比较,来判断是否相等
     */
     
    //浮点数的内部表达
    /*
     浮点数在计算时是由专用的硬件部件实现的
     计算double和float所用的部件是一样的
     */
    
    //选择浮点类型
    /*
     如果没有特殊需要,只使用double
     现代CPU能直接对double做硬件运算,性能不会比float差,在64位的机器上,数据存储的速度也不比float慢
     */
    
    return 0;
}

【逻辑类型】

//  main.c
//  Created by weichen on 15/4/8.
//  Copyright (c) 2015年 weichen. All rights reserved.
#include <stdio.h>
#include <stdbool.h>

int main(int argc, const char * argv[]) {
    // bool
    /*
     C语言本没有逻辑类型,在内部计算中使用整数表达关系运算和逻辑运算的结果,0表示false,而非0的值表示true。
     在C99中,也没有固定的逻辑类型,但是通过一个头文件定义了可以直接使用的true和false这两个值,以及bool这个类型。
     逻辑运算则是C语言固有的成分。
     
     #include <stdbool.h>
     之后就可以使用bool和true、false
    */     
    bool a = 6 < 5;
    bool b = true;
    
    printf("%d\n", a);  //0
    printf("%d\n", b);  //1
    
    //逻辑运算
    /*
     逻辑运算是对逻辑量进行的运算,结果只有0或1
     逻辑量是关系运算或逻辑运算的结果
     ! 逻辑非
     && 逻辑与
     || 逻辑或
     
     如果要表达数学中的区间,如:x∈(4,6) 或 x∈[4,6] 应该如何写C的表达式?
     像 4 < x < 6 这样的式子,不是C能正确计算的式子,因为 4 < x 的结果是一个逻辑值(0或1),
     应该写成 (x > 4 && x < 6) 或 (x >= 4 && x <= 6)
     判断一个字符a是否是大写字母? a >= 'A' && a <= 'Z'
     
     优先级    运算符         结合性
       ()            从左到右
       ! + - ++ --   从右到左(单目+和-)
       * / %         从左到右
       + -           从左到右
       < <= > >=     从左到右
       == !=         从左到右
       &&            从左到右
       ||            从左到右
    = += -= *= /= %= 从右到左
     
     */
    
    return 0;
}

【类型转换与条件运算】

//  main.c
//  Created by weichen on 15/4/8.
//  Copyright (c) 2015年 weichen. All rights reserved.
#include <stdio.h>

int main(int argc, const char * argv[]) {

    //自动类型转换
    //当运算符的两边出现不一致的类型时,会自动转换成较大的类型,能表达范围更大的数
    
    //char -> short -> int -> long -> long long
    //int -> float -> double
    
    //对于printf,任何小于int的类型会被转换成int;float会被转换成double
    //但是scanf不会,要输入short,需要%hd,即short int,要输入long long,需要%ld。 (h:短整数或单精度浮点数,l:长整数或双精度浮点数)
    
    
    // 强制类型转换的优先级高于四则运算
    //1. (类型)值
    double a = 1.0;
    double b = 2.0;
    int i = (int)a/b;
    int j = (int)(a/b);
    
    int c = 5;
    int d = 6;
    double e = (double)(c/d);
    
    printf("%d\n", i);
    printf("%d\n", j);
    printf("%lf\n", e);
    
    //2. 小的变量不总能表达大的量
    printf("%d\n", (short)32768);   //-32768,short最多能表示32767
    printf("%d\n", (char)32768);    //0
    
    //3. 强制类型转换只是从那个变量计算出了一个新的类型的值,它并不改变那个变量,无论是值还是类型都不改变
    int k = 32768;
    short kk = (short)k;
    printf("%d\n", k);  //32768
    
    //条件运算符
    //c = (count > 20) ? count - 10 : count + 10;
    //条件运算符的优先级高于赋值运算符,但是低于其他运算符
    
    
    //逗号运算符
    //逗号用来连接两个表达式,并以其右边的表达式的值作为它的结果。逗号的优先级是所有的运算符中最低的,所以它两边的表达式会先计算;逗号的组合关系是自左向右,所以左边的表达式会先计算,而右边的表达式的值就留下来作为逗号运算的结果。
    //在for中使用, for(i=0,j=0;i<j;i++,j--){},这里逗号划分两个表达式。
    int n;
    int m;
    n = 1+2,3+4;        //n=1+2是一个表达式,3+4没有用到,最终结果是3
    m = (1+2,3+4);      //组合关系,右边表达式的值作为结果
    printf("%d\n", n);  //3
    printf("%d\n", m);  //7
    
    return 0;
}

------分隔线----------------------------