C语言学习笔记——数据类型和常量变量
今天是 Mii 学习 C 语言的第三天。这两天 Mii 学习了 C 语言的数据类型和常量变量,话不多说,现在就把这两天学到的知识整理一下吧٩(๑•̀ω•́๑)۶
下面来盘点一下 C 语言的各种数据类型。不过 Mii 这两天学习的,主要是其中的内置数据类型。

1 char //character
2
3 char ch //使用char创建字符变量
在 C 语言中,字符要用一对单引号括起来,比如 'x'、'a'、'w',这些字符的类型就是 char。
1.2 整型
整型的英文单词是 integer,在 C 语言中用 int 表示整型类型。
1 int
2
3 int num;//使用int类型创建整型变量
在 C 语言中,100、20、35 这些整数的类型就是 int。
1.3 浮点型
1 float //单精度浮点型
2 double //双精度浮点型
3
4 float num1; //使用float创建变量
5 double num2; //使用double创建变量
在C语言中,3.14、5.5这些小数类型默认是double类型,3.14f这种写法表示float类型。
1.4布尔类型
C语言在C89/C90时期并没有为布尔值设置一个类型,使用整数0表示假,非零值表示真。后来在C99标准中也引入了布尔类型,是专门表示真假的。
1 _Bool
布尔类型的取值是:true或false,这两个符号是定义在<stdbool.h>头文件中的。
1 #define bool _Bool
2
3 #define false 0
4 #define ture 1
布尔类型的使用,一般得包含头文件<stdbool.h>
代码演示:
#include<stdio.h>
#include<stdbool.h>
int main()
{
_Bool YUZU = true;
if (YUZU)
printf("Ciallo~(∠·ω< )⌒★");
return 0;
}
一直到C23这个标准,才把bool、true、false定义为C语言关键字,使用bool类型,不再依赖<stdbool.h>这个头文件了。
2.类型修饰符
前面介绍的数据类型,其实已经解决一部分问题,但是在真实的开发过程中,还是不够,为了让内置类型提供更精细的数据表示能力,C语言中还引入了类型修饰符:
1 //和内存长度有关的
2 short
3 long
4
5 //和符号相关的
6 signed
7 unsigned
2.1 short和long
short和long是和内存长度有关的两个类型修饰符。
1 int //标准的整型
2
3 //修饰整型
4 short [int] //短整形
5 long [int] //长的整型
6 long long [int] //长的整型
7 //[]中的内容是可以省略的
8
9 //修饰浮点型
10 long double //C99中引入
- short和long是用来修饰整型类型。
- 常规的整型类型是int,长度是4个字节,short int类型的长度是2个字节。
- C语言标准规定long int的长度是大于等于int长度的。
要想知道每个数据的类型的长度,可以使用sizeof来计算,sizeof是C语言的一个操作符,sizeof可以算出一个数据类型的长度,单位是字节,使用方法是:
sizeof(type)
type就是对应的数据类型,sizeof计算的结果是size_t类型的,打印的时候应该使用%zu的占位符,下面演示代码:
#include<stdio.h>
#include<stdbool.h>
int main()
{
_Bool flag = true;
if (flag)
printf("I like C\\n");
printf("char: %zu\\n", sizeof(char));
printf("_Bool: %zu\\n", sizeof(_Bool));
printf("short: %zu\\n", sizeof(short));
printf("int: %zu\\n", sizeof(int));
printf("long: %zu\\n", sizeof(long));
printf("long long: %zu\\n", sizeof(long long));
printf("float: %zu\\n", sizeof(float));
printf("double: %zu\\n", sizeof(double));
printf("long double: %zu\\n", sizeof(long double));
return 0;
}
注:long和long double类型的长度,是和平台采用的数据模型有关的。
数据模型指的是在特定操作系统、CPU架构和ABI(应用程序二进制接口)下,C/C++等语言中基本数据类型(short、int、long、long long)以及指针类型的具体位宽(字节数)的约定。
下面是Mii的电脑算出的值
不同的电脑不同的编译器算出的值可能不同特别是long类型和long double,那么long的长度有时是4个字节,有时是8个字节,我们如果想要使用确切长度且和平台不同无关的整型类型该怎么办呢?
这个时候就要看stdint.h这个头文件,这里边提供了确切长度且和平台无关的整型类型,这些类型在嵌入式开发中使用很常见。
2.2 signed和unsigned
signed 和 unsigned 是和符号相关的两个类型修饰符,专门修饰字符型和整型类型的。
signed 关键字,表示一个类型带有正负号,可以表示正整数、负整数和0;unsigned 关键字,表示该类型不带有正负号,只能表示零和正整数。
| char | signed char | unsigned char |
| short [int] | [signed] short [int] | unsigned short [int] |
| int | [signed] int | unsigned int |
| long [int] | [signed] long [int] | unsigned long [int] |
| long long [int] | [signed] long long [int] | unsigned long long [int] |
对于int类型,默认是带有正负号的,也就是说int等同于signed int。由于这是默认情况,关键字signed一般都省略不写,但是写了也不算错。
但是,C 语言中 char 有可能是 signed char,也有可能是 unsigned char,具体等价于哪个是编译器的具体实现定义的。这一点和 int 类型是有差异的。
前面通过 sizeof 算出长度的类型是 size_t,size_t 就是无符号整型,因为长度不可能是负数。
sizeof 操作符的返回值,C 语言只规定是无符号整数,并没有规定具体的类型,而是留给系统自己去决定,sizeof 到底返回什么类型。不同的系统中,返回值的类型有可能是 unsigned int,也有可能是 unsigned long,甚至是 unsigned long long,对应的 printf() 占位符分别是 %u、%lu 和 %llu。这样不利于程序的可移植性。C 语言提供了一个解决方法,创造了一个类型别名 size_t,用来统一表示 sizeof 的返回值类型,对应当前系统的 sizeof 的返回值类型,可能是 unsigned int,也可能是 unsigned long long。size_t 类型的值,在打印时的占位符是 %zu。
2.3取值范围
我们看到不同的数据类型长度是不同的,长度不同又决定了存放的数据的范围是不同的,这里我们看一下不同数据类的取值范围。
整型家族的取值范围可以在 <limits.h>这个头文件中查看
浮点型家族的取值范围可以在<float.h>这个头文件中查看
| char | 1 | -128 到 127 |
| short | 2 | -32,768 到 32,767 |
| int | 4(32/64位系统) | -2,147,483,648 到 2,147,483,647 |
| long | 4 或 8 | -2,147,483,648 到 2,147,483,647(32位)/ -9.22e18 到 9.22e18(64位,实测) |
| long long | 8 | -9,223,372,036,854,775,808 到 9,223,372,036,854,775,807 |
| float | 4 | ±1.2E-38 到 ±3.4E+38,约 6-7 位有效数字 |
| double | 8 | ±2.3E-308 到 ±1.7E+308,约 15-16 位有效数字 |
| long double | 8 或 16 | 在 x86 架构下通常是 80 位(10 字节),取值范围比 double 更大 |
为了代码的可移植性,需要知道某种整数类型的极限值时,应该尽量使用这些常量。
-
SCHAR_MIN,SCHAR_MAX:signed char 的最小值和最大值。
-
SHRT_MIN,SHRT_MAX:short 的最小值和最大值。
-
INT_MIN,INT_MAX:int 的最小值和最大值。
-
LONG_MIN,LONG_MAX:long 的最小值和最大值。
-
LLONG_MIN,LLONG_MAX:long long 的最小值和最大值。
-
UCHAR_MAX:unsigned char 的最大值。
-
USHRT_MAX:unsigned short 的最大值。
-
UINT_MAX:unsigned int 的最大值。
-
ULONG_MAX:unsigned long 的最大值。
-
ULLONG_MAX:unsigned long long 的最大值。
3.ASCII字符集和转义字符
3.1 ASCII字符集
在C语言中,char类型是字符类型,用来表示字符,但也是属于整型家族的,那这些字符的值是多少呢?
比如:a的值是多少?x的值是多少呢?
这里的值可能根据计算机的不同而不同。因为不同的机器可能使用不同的字符集,当前我们见到的Windows/Linux/macOS平台上采用ASCII字符集,而在IBM大型机等老旧或专用系统还使用EBCDIC字符集,我们主要掌握现在主流的ASCII字符集就行。
在ASCII字符集中规定了,128个字符的对应的数值,如下图,后来ASCII码常被扩展为256个字符,目的是兼容更多国家语言中的字符。
下列码表含有全部128个ASCII十进制(dec)、八进制(oct)、十六进制(hex)及字符(ch)编码。
3. ASCII 码表(128 项)
| 0 | 0 | 00 | NUL (空) | 32 | 40 | 20 | (空格) | 64 | 100 | 40 | @ | 96 | 140 | 60 | ` |
| 1 | 1 | 01 | SOH (标题开始) | 33 | 41 | 21 | ! | 65 | 101 | 41 | A | 97 | 141 | 61 | a |
| 2 | 2 | 02 | STX (正文开始) | 34 | 42 | 22 | " | 66 | 102 | 42 | B | 98 | 142 | 62 | b |
| 3 | 3 | 03 | ETX (正文结束) | 35 | 43 | 23 | # | 67 | 103 | 43 | C | 99 | 143 | 63 | c |
| 4 | 4 | 04 | EOT (传送结束) | 36 | 44 | 24 | $ | 68 | 104 | 44 | D | 100 | 144 | 64 | d |
| 5 | 5 | 05 | ENQ (询问) | 37 | 45 | 25 | % | 69 | 105 | 45 | E | 101 | 145 | 65 | e |
| 6 | 6 | 06 | ACK (确认) | 38 | 46 | 26 | & | 70 | 106 | 46 | F | 102 | 146 | 66 | f |
| 7 | 7 | 07 | BEL (响铃) | 39 | 47 | 27 | ' | 71 | 107 | 47 | G | 103 | 147 | 67 | g |
| 8 | 10 | 08 | BS (退格) | 40 | 50 | 28 | ( | 72 | 110 | 48 | H | 104 | 150 | 68 | h |
| 9 | 11 | 09 | HT (横向制表) | 41 | 51 | 29 | ) | 73 | 111 | 49 | I | 105 | 151 | 69 | i |
| 10 | 12 | 0a | LF (换行) | 42 | 52 | 2a | * | 74 | 112 | 4a | J | 106 | 152 | 6a | j |
| 11 | 13 | 0b | VT (纵向制表) | 43 | 53 | 2b | + | 75 | 113 | 4b | K | 107 | 153 | 6b | k |
| 12 | 14 | 0c | FF (换页) | 44 | 54 | 2c | , | 76 | 114 | 4c | L | 108 | 154 | 6c | l |
| 13 | 15 | 0d | CR (回车) | 45 | 55 | 2d | – | 77 | 115 | 4d | M | 109 | 155 | 6d | m |
| 14 | 16 | 0e | SO (移出) | 46 | 56 | 2e | . | 78 | 116 | 4e | N | 110 | 156 | 6e | n |
| 15 | 17 | 0f | SI (移入) | 47 | 57 | 2f | / | 79 | 117 | 4f | O | 111 | 157 | 6f | o |
| 16 | 20 | 10 | DLE (退出数据链) | 48 | 60 | 30 | 0 | 80 | 120 | 50 | P | 112 | 160 | 70 | p |
| 17 | 21 | 11 | DC1 (设备控制1) | 49 | 61 | 31 | 1 | 81 | 121 | 51 | Q | 113 | 161 | 71 | q |
| 18 | 22 | 12 | DC2 (设备控制2) | 50 | 62 | 32 | 2 | 82 | 122 | 52 | R | 114 | 162 | 72 | r |
| 19 | 23 | 13 | DC3 (设备控制3) | 51 | 63 | 33 | 3 | 83 | 123 | 53 | S | 115 | 163 | 73 | s |
| 20 | 24 | 14 | DC4 (设备控制4) | 52 | 64 | 34 | 4 | 84 | 124 | 54 | T | 116 | 164 | 74 | t |
| 21 | 25 | 15 | NAK (反确认) | 53 | 65 | 35 | 5 | 85 | 125 | 55 | U | 117 | 165 | 75 | u |
| 22 | 26 | 16 | SYN (同步空闲) | 54 | 66 | 36 | 6 | 86 | 126 | 56 | V | 118 | 166 | 76 | v |
| 23 | 27 | 17 | ETB (传输块结束) | 55 | 67 | 37 | 7 | 87 | 127 | 57 | W | 119 | 167 | 77 | w |
| 24 | 30 | 18 | CAN (取消) | 56 | 70 | 38 | 8 | 88 | 130 | 58 | X | 120 | 170 | 78 | x |
| 25 | 31 | 19 | EM (媒介结束) | 57 | 71 | 39 | 9 | 89 | 131 | 59 | Y | 121 | 171 | 79 | y |
| 26 | 32 | 1a | SUB (替换) | 58 | 72 | 3a | : | 90 | 132 | 5a | Z | 122 | 172 | 7a | z |
| 27 | 33 | 1b | ESC (退出) | 59 | 73 | 3b | ; | 91 | 133 | 5b | [ | 123 | 173 | 7b | { |
| 28 | 34 | 1c | FS (文件分隔符) | 60 | 74 | 3c | < | 92 | 134 | 5c | \\ | 124 | 174 | 7c | | |
| 29 | 35 | 1d | GS (组分隔符) | 61 | 75 | 3d | = | 93 | 135 | 5d | ] | 125 | 175 | 7d | } |
| 30 | 36 | 1e | RS (记录分隔符) | 62 | 76 | 3e | > | 94 | 136 | 5e | ^ | 126 | 176 | 7e | ~ |
| 31 | 37 | 1f | US (单元分隔符) | 63 | 77 | 3f | ? | 95 | 137 | 5f | _ | 127 | 177 | 7f | DEL (删除) |
也可以通过代码看一下这些字符对应的数值。
#include<stdio.h>
int main()
{
printf("%d\\n", 'x');
printf("%d\\n", '#');
return 0;
}
3.2转译序列
通常情况下字符是被单引号括起来的单个字符,比如:‘a’,‘x’,但是ASCII码值从0~31的字符是不可打印字符,为了使程序可以处理字符集中的每一个字符,C语言提供了一种特殊的表示法:转义序列。
转义序列有2种:字符转义序列和数字转义序列。
字符转义序列
| \\? | 在书写连续多个问号时使用,防止他们被解析成三字母词,在新的编译器上没法验证了。 |
| \\' | 用于表示字符常量 ' |
| \\" | 用于表示一个字符串内部的双引号 |
| \\\\ | 用于表示一个反斜杠,防止它被解释为一个转义序列符。 |
| \\a | 警报,这会使得终端发出警报声或出现闪烁,或者两者同时发生。 |
| \\b | 退格键,光标回退一个字符,但不删除字符。 |
| \\f | 换页符,光标移到下一页。在现代系统上,这已经反映不出来了,行为改成类似于 \\v。 |
| \\n | 换行符,一般使用在屏幕上打印信息时,实现换行的效果 |
| \\r | 回车符,光标移到同一行的开头。 |
| \\t | 制表符,光标移到下一个水平制表位,通常是下一个 4/8 的倍数。 |
| \\v | 垂直分隔符,光标移到下一个垂直制表位,通常是下一行的同一列。 |
数字转译序列
| \\ddd | ddd 表示 1~3 个八进制的数字。如:\\130 表示 'X' | 字符的 8 进制表示形式 |
| \\xdd | dd 表示 2 个十六进制数字。如:\\x30 表示字符 '0' | 字符的 16 进制表示形式 |
数字转义序列可以表示ASCII字符集中的所有字符。
需要把一个字符写成数字转义序列,查看一下ASCII字符集中,字符对应的8进制数值和16进制数值就很好转化了。
4.变量和常量
4.1变量
变量命名的一般规则:
- 变量的名字起得要有意义,见名知意。
- 只能由字母(包括大写和小写)、数字和下划线(‘_’)组成。
- 不能以数字开头。
- 长度不能超过63个字符。
- 变量名中区分大小写的。
- 变量名不能使用关键字。
变量的创建方法如下
char ch;
int age;
double weight;
变量在创建的时候给一个初始值,就叫初始化,如下所示:
char ch='w';
int age=18;
double weight=48.0;
4.2变量的分类
全局变量:在函数之外定义的变量称为全局变量
- 作用域:从定义位置开始,到整个源文件末尾都可见(如果其他文件想用,可通过 extern 声明)。
- 生命周期:在程序启动时创建,程序结束时才销毁(存储在内存的静态存储区/数据段)。
- 初始值:如果没有显式初始化,系统会自动初始化为0(或 ‘\\0’、NULL)。
- 使用注意:过多使用全局变量会导致模块间耦合度高、调试困难,建议谨慎使用。
全局变量代码演示:
#include<stdio.h>
int a = 100;//全局变量
void show()
{
printf("全局变量值:%d\\n", a);
}
int main()
{
show();
a = 200;
printf("修改后:%d\\n", a);
return 0;
}
局部变量:在大括号内部定义的变量就是局部变量
- 作用域:仅限于定义它的函数或代码块内部,外部无法访问。
- 生命周期:在进入函数/代码块时创建,退出时自动销毁(存储在内存的栈区)。
- 初始值:如果没有显式初始化,其值是垃圾值(不确定的随机数),建议对局部变量进行初始化。
- 优先级:当局部变量与全局变量同名时,优先使用局部变量。
局部变量代码演示:
void func()
{
int localVar = 10;//局部变量
printf("%d\\n", localVar);
}
int main()
{
//printf("%d\\n", localVar);//错误!main函数无法访问func中的localVar
return 0;
}
4.3常量
C语言中常量和变量的定义形式有所差异。
C语言中常量分为以下几种:
- 字面常量
- const修饰的常变量——>const=只读,不能被修改;被const修饰的变量不能被修改具有常量的属性
- #define定义的标识符常量
- 枚举常量
啊~!就写这么多吧,Mii写累了(;´Д`)
网硕互联帮助中心





评论前必须登录!
注册