第3章 数据和C(2)

发布于 2021-03-20  94 次阅读


3.4.3 使用字符:char类型

char类型用于存储字符(字母或标点符号),从技术层面来看,char是整数类型,char类型实际存储的是整数而不是字符。
ASCII编码。
整数65代表A;
A以整数65存储;
ASCII编码范围0~127.只需7位二进制数表示。通常,char类型被定义为8位的存储单元。一般而言C语言会保证char类型足够大,以存储系统(实现C语言的系统)的基本字符集。
C语言把1字节定义为char类型占用的位(bit)数,因此无论是16位还是32位系统,都可以使用char类型。

  1. 声明char类型变量
    char response;
    char itable,laten;
    以上声明创建了3个char类型的变量;
  2. 声明常量和初始化
    如果要把一个字符常量初始化位字母A;
    char grade = 'A';
    在C语言中,用单引号括起来的单个字符字符常量(character constant)

    char broiled:   //声明一个char类型的变量
    broiled = 'T';    //为其赋值,正确
    broiled = T;    //错误!此时T是一个变量
    broiled = "T" //错误,此时"T"是一个字符串
    //也可以这样子
    char grade = 65 //对ASCII没问题,但是这样是不好的编程的习惯
    • 因为'B'本来可以存在32位上但实际存在8位上;
    • 所以可以定义一个字符常量'FATE'存储在一个32位的存储单元上。但是只有后八位有效;
    • 若赋给grade,只有后8位有效,grade的值是'E'
  3. 非打印字符
    单引号只试用于字符、数字和标点符号,浏览ASCII,有些无法打印,例如(退格,换行,蜂鸣)
    (1)使用ASCII码表示
    例如蜂鸣器:ASCII=7

    char beep = 7;

    (2)特殊符号表示的字符,转义序列。
    file

。。整数类型不同形式
file
使用ASCII码时,注意数字和数字字符的区别,例如:字符4对应的ASCII码是52,'4'表示字符4而不是数值4.

  • 双引号中的字符集叫字符串。
    例如:

    printf("hello!\007\n");
    printf("hello!7\n");
  • 在转义序列和ASCII码中选择,尽量选择转义序列('\f'),其在不使用ASCII码的系统中仍然有效。

  • 使用('\032')比不带反斜杠更能让人理解意思

4.打印字符
printf()函数用%c 指明待打印的字符。 一个字符 变量实际上存储的为1个字节的整数值。如果用d%说明char打印的为一个整数。
而%c则是告诉printf()打印该整数值对应的字符。

//charcode.c-显示字符的代码编号
#include<stdio.h>
int main(void)
{
    char ch;

    printf("Please Enter a character.\n");
    scanf("%c",&ch);  //用户输入字符
    printf("The code for %c is %d.\n",ch,ch);

    return 0;
}

结果:
file

  1. 有符号还是无符号
    有些C编译器把char实现为有符号数,char范围为“-128~127”
    有些无符号“0-255”(limits.h)
    signed char and unsigned(C90)

    3.4.4 _bool类型

    程序通过布尔值可选择执行哪部分代码.

    3.4.5 可移植类型:stdint.h和inttypes.h

    C99新添加的两个头文件,确保了C语言的类型在各系统中的功能相同。
    例如:int32_t表示32位有符号整数类型。在使用32位int操作系统中,头文件会把int32_t作为int的别名。。。等
    使用int32_t类型编写程序,并包含stdio.h头文件时,编译器会把int或者long替换成当前系统匹配系统的类型。
    精度宽度整数类型:(追求空间)
    最快最小宽度类型:(追求速度)
    C标准针对%d、%ld提供了一些字符串宏来显示可移植性。例如:inttypes.h头文件中定义了PRId32字符串宏,代表打印32位有符号数值的合适转换说明。

    // altnames.c --- 可移植整数类型名
    #include<stdio.h>
    #include<inttypes.h>  //支持可移植类型
    int main(void)
    {
    int32_t me32;       //me32是一个32位有符号整数变量
    
    me32=  45933945
    printf("First,assume int32_t is int:");
    printf("me32=%d\n",me32);
    printf("Next,let's not make any assumptions.\n");
    printf("Instead,use a \"macro\" from inttypes.h:");
    printf("me32 = %"PRId32 "\n",me32);
    
    return 0;
    }

    执行结果:
    file

    3.4.6 float、double和long double

    file
    通常(float) 系统存储一个浮点数要占用32位,其中8位用于表示指数的值和符号,剩下24位用于表示非指数部分(也叫做尾数或有效数)及其符号。至少保证6位有效数字。
    10^{-37}---10^{+37}
    double(双精度)最小取值范围相同,但是至少能表示10位有效数字。
    一般情况下double占用64位
    C语言的第三种浮点类型是long double。

  2. 声明浮点型变量

    float noah,jonah;
    double trouble;
    float planck = 6.63e-34;
    long doble gnp;
  3. 浮点型常量
    浮点常量的基本形式是:有符号的数字(包括小数点),后面紧跟e或E,最后一个有符号数表示10的指数。

    
    -1.56E+12
    2.87e-3
    3.14159
    .2
    4e16
    .8E-5

默认情况下,编译器假定浮点型常量是double类型的精度。例如:假设some是float类型的变量

some = 4.0 * 2.0;

数字使用l或者L后缀。可以使数字类型称为long double类型。

  1. 打印浮点值
    printf使用%f转换说明打印十进制计数法的float和double类型浮点数,用%e打印指数计数法的浮点数。
    打印long double类型要用%LF、%Le或%La转换说明,

    // showf_pt.c-----以两种方式显示float类型的值
    #include<stdio.h>
    int main(void)
    {
    float aboat = 32000.0;
    double abet =2.14e9;
    long double dip = 5.32e-5;
    
    printf("%f can be written %e \n",aboat,aboat);    //下一行要求编辑器支持C99或其中的相关特性
    printf("And it's %a in hexadecimal,powers of 2 notation\n",aboat);
    printf("%f can be written %e\n",abet,abet);
    printf("$Lf can be written %Le\n",dip,dip);
    
    return 0;
    }

    file

  2. 浮点值的上溢和下溢
    C语言把损失了类型全精度的浮点值称为低于正常的浮点值(下溢)
    特殊的浮点值 NaN(not a number)
    浮点数舍入错误

    // floaterr.c-----演示舍入错误
    #include<stdio.h>
    int main(void)
    {
    float a,b;
    
    b=2.0e20+1.0;
    a=b-2.0e20;
    print("%f\n",a);
    
    return 0;
    }

file
错误原因:计算机缺少足够的小数位数来完成正确的运算

国际表示标准

3.4.7 复数和虚数类型

C语言有3种表示复数类型:float_Complex、double_Complex和long double_Complex;
例如float_Complex类型的变量应该包含两个float类型的值,分别表示负数的实部和虚部。
类似的。C语言的3种虚数类型是float_Imaginary...

如果包含<complex.h>头文件便可用complex代替_Complex。类似的imaginary代替_Imaginary.

3.4.8 其他类型

指针:指向变量或其他数据对象位置。

例如在 scanf()函数中用到的前缀&,便创造了一个指针,告诉scanf把数据放在何处。

小结

  • 关键字
  • 有符号整型
  • 无符号整型
  • 字符类型
  • _Bool类型
  • 实浮点类型
  • 负数和虚数浮点数

如何声明简单变量:

  1. 选择需要的类型
  2. 使用有效的字符给变量起一个变量名
  3. 按以下格式进行声明:
    类型说明符 变量名;
    类型说明符由一个或多个关键字组成。
  4. 可以同时声明相同类型的多个变量,用逗号分隔各变量名。
  5. 在声明的同时还可以初始化变量

    3.4.9 类型大小

    //typesize.c------打印类型大小
    #include<stdio.h>
    int main(void)
    {
    //C99为类型大小提供的%zd抓换说明
    printf("Type int %zd bytes.\n",sizeof(int));
    printf("Type char %zd bytes.\n",sizeof(char));
    printf("Type long %zd bytes.\n",sizeof(long));
    printf("Type double %zd bytes.\n",sizeof(double));
    printf("Type long double %zd bytes.\n",sizeof(long double));
    
    return 0;
    }

    file
    limits.h和float.h头文件中有类型限制的相关信息

    3.5 使用数据类型

    编写程序应该合理的选择所需的变量及类型.
    通常,int或者float表示数字,char表示字符。例如:

    int apples = 3      //right
    int oranges = 3.0   //not good

    int只保证整数,而float最多只保证(小数点)前6位。
    一般而言:变量i_前缀表示int类型us_前缀表示unsigned short类型。。。

    3.6 参数陷阱

    无论双引号中包含多少个字符和标点符号(printf),一个字符串就是一个参数。
    与此类似scanf("%d",&weight)函数调用有两个参数:"%d"和&weight。printf()和scanf()函数与一般函数不同,他们的参数是可变的。程序要知道参数的个数才能正常工作。例如:
    (三个参数)

    printf("%d cats ate %d cans of tuna\n",cats,cans);

    程序员要负责确保转换说明的数量、类型与后面参数的数量、类型相匹配。

    c语言通过函数原型机制检查函数调用时参数的个数和类型是否正确。
    但是!该机制对printf()和scanf()不起作用

    如果错误如下例子:

 // badcount.c  -- 参数错误的情况
 #include<stdio.h>
 int main(void)
 {
    int n = 4;
    int m = 5;
    float f = 7.0f;
    float g = 8.0f;

    printf("%d\n",n,m);           //参数太多
    printf("%d %d %d\n",n);       //参数太少
    printf("%d %d\n",f,g);        //类型不匹配

    return 0;
}

file

3.7 转义序列示例

推格(\b)水平制表符(\t)回车(\r)

//  escape.c    --使用转义序列
#include<stdio.h>
int main(void)
{
    float salary;

    printf("\aEnter your desired monthly salary:");
    printf("$_____\b\b\b\b\b");
    scanf("%f",&salary);
    printf("\n\t$%.2f a moth is $%.2f a year.",salary,salary * 12.0);
    printf("\rGee!\n");

    return 0;

}

file

3.7.1 程序运行情况

file

3.7.2 刷新输出

最初,printf()语句把输出发送到一个叫做缓冲区(buffer)的中间存储区域,然后缓冲区中的内容再不断被发送到屏幕上。

3.8 关键概念+小结

file


擦肩而过的概率