大话C语言:第5篇 数据类型

1 数据类型分类

        数据类型指的是用于声明不同类型的变量或函数的一个广泛的系统。数据类型决定了存储占用的空间,以及如何解释存储的位模式。

        C语言的数据类型分为以下几类:

  • 基本数据类型:整数类型、字符类型、浮点数类型和布尔类型。

  • 枚举类型:本质上也是算术类型,被用来定义在程序中只能赋予其一定的离散整数值的变量。

  • void 类型:表示没有值的数据类型,通常用于函数返回值。

  • 聚合类型:数组类型、指针类型和结构体类型。

2 基本数据类型

2.1 整数数据类型

数据类型字节数格式符数据范围最小值宏最大值宏
short(短整型)2%hd-215 ~ 215-1 (-32768 ~ 32767)SHRT_MINSHRT_MAX
int(整型)4%d-231 ~ 231-1 (-2147483648 ~ 2147483647)INT_MININT_MAX
long(长整型)4%ld-231 ~ 231-1 (-2147483648 ~ 2147483647)LONG_MINLONG_MAX
long long(长长整型)8%lld-263 ~ 263-1LLONG_MINLLONG_MAX
unsigned short(无符号 短整型)同 short%hu0 ~ 216-1 (0 ~ 65535)0USHRT_MAX
unsigned int(无符号 整型)同 int%u0 ~ 232-1 (0 ~ 4294967295)0UINT_MAX
unsigned long(无符号 长整型)同 long%lu0 ~ 232-1 (0 ~ 4294967295)0ULONG_MAX
unsigned long long(无符号 长长整型)同 long long%llu0 ~ 264-10ULLONG_MAX

        由于C 标准没有具体规定以上各类数据所占用的字节数。因此,在不同系统、编译器下,数据类型占用的字节数会有所不同。例如,long 类型,相同的 gcc 编译器下,在 Windows 系统中占 4 字节,而在 Linux 系统中占 8 字节。

        为了得到某个类型或某个变量在特定平台上的准确大小,可以使用 sizeof 运算符,语法格式包括以下两种方式:

  • sizeof(数据类型):

/*
sizeof(int) 直接打印int类型占用内存大小。
查看sizeof 返回的占用内存大小,需要使用 %lu 格式符
*/
printf("%lu\n", sizeof(int));
  • sizeof(变量名):

int var = 100;
/*
sizeof(var) 直接打印var 变量占用内存大小。
查看sizeof 返回的占用内存大小,需要使用 %lu 格式符
*/
printf("%lu\n", sizeof(var));

可以使用 sizeof 查看 整数类型占用内存的大小,代码示例:

#include <stdio.h>
​
int main(void)
{
    // 查看short内存占用
    printf("short占用内存大小 = %lu\n", sizeof(short));
    
    // 查看int内存占用
    printf("int占用内存大小 = %lu\n", sizeof(int));
​
    // 查看long内存占用
    printf("long占用内存大小 = %lu\n", sizeof(long));
​
    // 查看long long内存占用
    printf("long long占用内存大小 = %lu\n", sizeof(long long));
​
    return 0;
}

        可以引入头文件 #include <limits.h> 借助宏来查看 数据类型在当前平台上 对应的最小、最大值,代码示例:

#include <stdio.h>
#include <limits.h>
​
int main(void)
{
    // 查看short类型最大最小值
    printf("short 最小值 = %hd, 最大值 = %hd\n", SHRT_MIN, SHRT_MAX);
    printf("unsigned short 最小值 = 0 最大值 = %hu\n", USHRT_MAX);
    
    // 查看int类型最大最小值
    printf("int 最小值 = %d,最大值 = %d\n", INT_MIN, INT_MAX);
    printf("unsigned int 最小值 = 0, 最大值 = %u\n", UINT_MAX);
​
    // 查看long类型最大最小值
    printf("long 最小值 = %ld, 最大值 = %ld\n", LONG_MIN, LONG_MAX);
    printf("unsigned long 最小值 = 0 最大值 = %lu\n", ULONG_MAX);
    
    // 查看long long类型最大最小值
    printf("long long 最小值 = %lld, 最大值 = %lld\n", LLONG_MIN, LLONG_MAX);
    printf("unsigned long long 最小值 = 0, 最大值 = %llu\n", ULLONG_MAX);
​
    return 0;
}

2.2 浮点类型

        在计算机内部以浮点方式表示(小数点是浮动的),因此也叫浮点型。浮点类型包括:

  • float (单精度)

  • double (双精度)

        浮点数据没有八、十六进制,也没有 unsigned 无符号形式。在计算机底层采用的是近似计算,实现比较复杂,且不同平台处理方式不同。下表列出了关于标准浮点类型的存储大小、取值范围和精度的细节:

类型字节数格式符有效数字常量后缀
float (单精度)4%f6~7f
double (双精度)8%lf15~16

系统默认看作double 类型。如想指明为 float 类型,需加后缀 f,3.14f。

关于浮点类型有效数字需要注意以下几点:

  • 有效数字6~7:

    • 整数部分 + 小数部分 <= 6 位, 准确。

    • 整数部分 + 小数部分 == 7 位,可能准确,也可能不准确。

    • 整数部分 + 小数部分 > 7位。大多不准确。

  • 有效数字15~16:

    • 整数部分 + 小数部分 <= 15 位, 准确。

    • 整数部分 + 小数部分 == 16 位,可能准确,也可能不准确

    • 整数部分 + 小数部分 > 16位。大多不准确。

显示小数时,%f 和 %lf 默认保留 6 位小数。

        如需指定小数位数,使用格式符 %.nf ,n 为几,表示精确到小数点后几位,会对 n+1 位做 4 舍 5 入。代码示例:

#include <stdio.h>
​
int main(void)
{
    // 定义20位小数的float变量pi
    float pi1 = 3.14159265358979323846f;
    
    // 定义20 位小数的double变量pi
    double pi2 = 3.14159265358979323846; 
​
    printf("f=%.20f\n", pi1);
    printf("d=%.20lf\n", pi2);
​
    return 0;
}

2.3 字符类型

        C语言定义 char 类型来表示字符数据。 其本质依然是存储数值,因此与数值型类似,也有有符号、无符号之分。占用 1 个字节内存大小。

类型字节数格式符数据范围最小值宏最大值宏
char1%hhd-27 ~ 27-1 (-128 ~ 127)CHAR_MINCHAR_MAX
unsigned char1%hhu0~28-1 (0 ~ 255)0UCHAR_MAX

2.3.1 ASCII 码

        char 类型在程序中,最常用来表示字符。其本质依然是一个数字,但每个值都对应一个固定的字符,共定义了128个字符。称之为 ASCII 码 (American Standard Code for Information Interchange) 美国信息交换标准代码。

ASCII值控制字符ASCII值字符ASCII值字符ASCII值字符
0NUL32(space)64@96
1SOH33!65A97a
2STX34"66B98b
3ETX35#67C99c
4EOT36$68D100d
5ENQ37%69E101e
6ACK38&70F102f
7BEL3971G103g
8BS40(72H104h
9HT41)73I105i
10LF42*74J106j
11VT43+75K107k
12FF44,76L108l
13CR45-77M109m
14SO46.78N110n
15SI47/79O111o
16DLE48080P112p
17DCI49181Q113q
18DC250282R114r
19DC351383S115s
20DC452484T116t
21NAK53585U117u
22SYN54686V118v
23TB55787W119w
24CAN56888X120x
25EM57989Y121y
26SUB58:90Z122z
27ESC59;91[123{
28FS60<92\124|
29GS61=93]125}
30RS62>94^126~
31US63?95_127DEL

注意:我们从键盘键入的所有内容都是字符。如,键入数字 1,实际是字符 ‘1’,真正存储在计算机内的是 49(字符 1 的 ASCII 码值),而如果我们键入了 35,实际上这是两个字符。真正存储在计算机内的是 51 和 53(字符 3 和 字符 5 的 ASCII 码值)。我们可以用 printf 结合 格式符 %c,显示字符。 如果用 %d,就显示 其 ASCII 值了。代码示例:

#include <stdio.h>
​
int main(void)
{
    char ch = 53;
    printf("ASCII为:%d, 字符为:%c\n", ch, ch);
    return 0;
}

2.3.2 转义字符

        C 语言提供了一类特殊的字符,是由 \ 和特定字符组合而成,称之为 转义字符。它们都是 一个 字符,例如:

  • ‘\n’ 这是 1 个字符。 代表 回车换行(回车键)。

  • ‘\t’ 也是 1 个字符。代表 制表符 (Tab键)。

  • ‘\b’ 同样是 1 个字符。 代表 退格符(Backspace 键)。

  • ‘\0’ 是一个字符。代表 空。对应 ASCII 值 0。

  • ‘\ddd’ 是一个字符。ddd 对应 3 个八进制数(没有用 0 开头)。 如:\141 对应 ASCII 值为 97,代表 ‘a’。

  • ‘\xhh’ 是一个字符。x 表十六进制,hh 对应 2 个十六进制数。 如:\x41 对应 ASCII 值为 65,代表 ‘A’。

\ 还可以在特定环境下,将一个字符还原其本身意。例如,现在想在 printf(“%d\n”,10);输出 10 的时候,用 “” 把 10 包裹住。 如果直接写 printf(“ “%d” \n”,10);是会报错的。这时,可以使用 \" 将 “ 进行转义,还原其本身意。

printf("\"%d\"", 10);  // 这里的 \" 看作一个双引号字符。

类似的还有:

  • \' 代表 单引号。

  • \\ 代表 反斜杠。

2.3.3 字符输入输出

C 语言提供了专门的函数,方便在程序中 获取、输出 字符数据。

  • getchar():获取用户从键盘写入的一个字符。

    • ​​程序执行到 getchar() 会暂停,等待用户键入字符数据。

    • 一次 getchar() 调用,只读取一个字符。如用户键入多个字符,需要多次调用 getchar()读取。

    • 函数调用完成,会返回实际读到的字符 对应的 ASCII 值。

    • 用户键入字符结束,敲的回车键,对应‘\n’ 字符,也可以使用 getchar() 读取。

int ret = getchar();
  • putchar(ch):将 ch 对应的字符,输出到屏幕。

    • ch 可以是变量也可以是常量。

    • 一次 putchar() 调用,只写出一个字符(不含换行符 ‘\n’)。

    • 函数调用完成,会返回实际写出的字符 对应的 ASCII 值。

char ch = 'A';
int ret = putchar(ch);

2.4 布尔类型

        C语言在设计之初是没有真正意义上的布尔类型的,使用 1 和 0,对应表示真、假。但是,其他编程语言像 C++、java 都设计有布尔数类型。 C语言在1999 年推出的新标准(C99)中,也加入了 布尔类型。用 true 来代表 1,为真;用 false 来代表 0,为假。使用时,需要引入头文件 #include <stdbool.h>

#include <stdbool.h>
​
int main(void)
{
    printf("%d, %d\n", true, false);
    return 0;
}

        虽然语法上与其他语言一致,但 C 语言每次在使用时需先引入头文件,较为麻烦。 因此,一些工程师还是喜欢直接在程序中用 1 和 0 来表示 真和假。

3 基本类型转换

        基本类型转换是将一个数据类型的值转换为另一种数据类型的值。C 语言中有两种类型转换:

  • 隐式类型转换:隐式类型转换是在表达式中自动发生的,无需进行任何明确的指令或函数调用。它通常是将一种较小的类型自动转换为较大的类型,例如,将int类型转换为long类型或float类型转换为double类型。隐式类型转换也可能会导致数据精度丢失或数据截断。

int i = 10;
float f = 3.14;
double d = i + f; // 隐式将int类型转换为double类型
  • 显式类型转换:显式类型转换需要使用强制类型转换运算符(type casting operator),它可以将一个数据类型的值强制转换为另一种数据类型的值。强制类型转换可以使程序员在必要时对数据类型进行更精确的控制,但也可能会导致数据丢失或截断。

double d = 3.14159;
int i = (int)d; // 显式将double类型转换为int类型
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值