C语言基础(三)【数据类型与变量】
通过本篇文章可以学习C语言的一些数据类型及相应的长度,其中解释了 signed 和 unsigned 的作用,还有一些变量和常量的使用及一些示例,最后还可以学习ASCII编码及转义字符的作用。
文章目录
前言
在本篇【数据类型与变量】中,我们将介绍C语言中的相关数据类型体系以及学习如何声明变量、初始化变量等这些基础知识,这将为我们后续学习C语言知识打下坚实的基础。
一、C语言的数据类型
C语言中的数据类型主要分为两大类:基本数据类型和构造数据类型(本篇主要介绍基本数据类型)。
1.基本数据类型
(1):整型
int:基本的整型,根据编译器和平台的不同,其大小可能有所不同,但通常是16位、32位或64位。
short 或 short int:短整型,通常占用比int更少的存储空间。
long 或 long int:长整型,通常占用比int更多的存储空间。
long long 或 long long int:长长整型,用于存储非常大的整数。
unsigned int、unsigned short、unsigned long、unsigned long long:无符号整型,这些类型只能存储非负值,并且它们的存储范围比相应的有符号类型大一倍。
(2):浮点型
float:单精度浮点型,用于存储带小数点的数值。
double:双精度浮点型,提供比float更高的精度。
long double:扩展精度浮点型,其精度至少与double相同,但可能更高。
(3):字符型
char:字符型,用于存储单个字符(如字母或标点符号)。根据编译器和平台的不同,char可能是有符号的或无符号的,但通常用于存储ASCII字符。
(4):布尔类型
其实C语言标准中没有直接的布尔类型。但是,<stdbool.h> 头文件(布尔类型的使用需包含该头文件)定义了 bool、true 和 false,它们通常用于表示布尔值。在没有 <stdbool.h> 的情况下,人们常常使用int类型来表示布尔值,其取值中 0 表示假(false),非 0 值表示真(true)。
示例:
#include<stdio.h>
#include<stdbool.h>
int main()
{
bool flag = true;
if(flag)
{
printf("hello\n");
}
return 0;
}
输出结果:
2.构造数据类型
C语言中的构造数据类型是由基本数据类型(如整型、浮点型、字符型等)按照一定规则组合而成的复杂数据类型,用于表示更复杂的数据结构。
(1):数组
数组是一种数据结构,用于存储相同类型数据的集合。数组中的每个元素可以通过索引来访问,索引通常是从0开始的。
(2): 结构体
结构体是一种复合数据类型,允许将不同类型的数据项组合成一个单一的类型。结构体中的每个数据项可以单独访问。
(3):联合体
定义:联合体是一种特殊的数据结构,允许在相同的内存位置存储不同的数据类型,但一次只能使用其中一种类型。
(4):枚举
虽然枚举类型在某些方面与基本数据类型相似(如它们都是用来表示一组预定义的值),但它也被视为一种构造数据类型。
3. signed 和 unsigned 的作用
C语言会使用 signed 和 unsigned 关键字修饰字符型和整型。
(1):signed:表示一个类型带有正负号,包含负值。
默认情况:在C语言中,如果不明确指定一个整型变量是 signed 还是 unsigned,那么默认情况下,它会被视为 signed。如对于 int 类型,默认是带有正负号的,也就是说 int 等同于 signed int,由于这是默认情况,关键字 signed 一般都省略不写,但是写了也不会错。
注意:但C语言规定 char 类型默认是否带有正负号,由当前系统决定。这就是说, char 不等同于 signed char ,它有可能是 signed char ,也有可能是 unsigned char。
(2):unsigned:表示该类型不带有正负号,只能表示0和正整数。
整数变量声明为 unsigned 的好处是,同样长度的内存能够表示的最大整数值,增大了一倍。比如,16位的 signed short int 的取值范围是:-32768-32767,最大是32767,而 unsigned short int 的取值范围是:0-65535,最大值为65535.
4.基本数据类型的长度(计算)
每⼀种数据类型都有自己的长度,使用不同的数据类型,能够创建出长度不同的变量,变量长度的不同,存储的数据范围就有所差异。
(1):sizeof操作符
sizeof 是一个关键字,也是操作符,专们是用来计算sizeof操作符数的类型长度的,单位是字节。sizeof 操作符的操作数可以是类型,也可是变量或者表达式。
示例:
sizeof( 类型 )
sizeof 表达式
sizeof 的操作数如果不是类型,是表达式的时候,可以省略掉后边的括号的。
sizeof 后边的表达式是不真实参与运算的,根据表达式的类型来得出大小。
sizeof 的计算结果是 size_t 类型的。
注意: sizeof 运算符的返回值,C 语言只规定是无符号整数,并没有规定具体的类型,而是留给系统自己去决定, sizeof 到底返回什么类型。但C 语言提供了一个解决方法,创造了一个类型别名 size_t ,用来统一表示 sizeof 的返回值类型。对应当前系统的 sizeof 的返回值类型,可能是 unsigned int ,也可能是 unsigned long long 。
#include <stdio.h>
int main()
{
int k = 20;
printf("%zd\n", sizeof(k)); //2
printf("%zd\n", sizeof k); //3.k是变量的名字,可以省略掉sizeof后边的()
printf("%zd\n", sizeof(int)); //4
printf("%zd\n", sizeof(4 + 3.6)); //5
return 0;
}
(2):使用 sizeof 操作符计算变量k(即一个整型变量)的大小,并将结果作 size_t 类型传递给 printf 函数。然后,printf 函数使用 %zd 格式来打印这个大小。由于 k 是 int 类型,所以打印出来的大小将是 int 类型在内存中占用的字节数(通常是4字节)。
(3):k是变量的名字,可以省略掉 sizeof 后边的()
(4):直接计算 int 类型的大小,并打印出来。sizeof 可以直接作用于类型。
(5):这里有一个微妙的一点:4 + 3.6是一个浮点数表达式(因为涉及到浮点数3.6),所以整个表达式的结果是一个 double 类型的值。因此,sizeof(4 + 3.6) 实际上计算的是 double 类型的大小,并将其打印出来。
注意:上述(5)的计算与表达式的值无关,只与表达式的类型有关。
(6):基本数据类型的长度
#include <stdio.h>
int main()
{
printf("char: %zd\n", sizeof(char)); //1
printf("bool: %zd\n", sizeof(bool)); //1
printf("short: %zd\n", sizeof(short)); //2
printf("int: %zd\n", sizeof(int)); //4
printf("long: %zd\n", sizeof(long)); //4
printf("long long: %zd\n", sizeof(long long)); //8
printf("float: %zd\n", sizeof(float)); //4
printf("double: %zd\n", sizeof(double)); //8
printf("long double: %zd\n", sizeof(long double)); //8
return 0;
}
输出结果:
二、变量声明与初始化
C语言中把经常变化的值称为变量,不变的值称为常量。
1.全局变量
在大括号外部定义的变量就是全局变量。全局变量的使用范围更广,整个工程中想使用,都是有办法使用的。
2.局部变量
在大括号内部定义的变量就是局部变量。局部变量的使用范围是比较局限,只能在自己所在的局部范围内使用的。
示例:
#include <stdio.h>
int global = 1; //全局变量
int main()
{
int local = 2; //局部变量
printf("%d\n", local);
printf("%d\n", global);
return 0;
}
注意:但当全局变量和局部变量同名的时候,局部变量优先使用。
示例:
#include <stdio.h>
int k = 10; //全局变量
int main()
{
int k = 20; //局部变量
printf("k = %d\n", k);
return 0;
}
输出结果:
3.一些变量在内存中的存储位置(略讲)
在C语言中,变量的存储通常可以划分为以下几种内存区域:栈区、堆区、全局/静态存储区、常量区、代码区。
(1):栈区:栈区用于存储局部变量和函数调用的上下文。
(2):堆区:堆区是程序在运行时动态申请和释放内存的区域(动态内存管理)。
(3):全局/静态存储区:全局变量和静态变量存储在全局/静态存储区中。
(4):常量区:常量区用于存储字符串常量和编译时确定的常量值。
(5):代码区:代码区用于存储程序的机器指令代码。
4.声明及初始化
(1):声明变量时,要指定了变量的类型以及变量名。
data_type name;
| |
| |
数据类型 变量名
示例:
int a; // 声明了一个整型变量a
float b; // 声明了一个浮点型变量b
char c; // 声明了一个字符型变量c
(2):变量在创建的时候就给一个初始值,就叫初始化
nt a = 5; // 声明并初始化了整型变量a,其值为5
float b = 3.14; // 声明并初始化了浮点型变量b,其值为3.14
char c = 'A'; // 声明并初始化了字符型变量c,其值为'A'
三、常量的定义与使用
在C语言中,常量是程序中值不可变的量。常量可以是任何基本数据类型,如整型(int)、浮点型(float、double)、字符型(char)等,或者是指针类型。
1.定义常量
(1):#define 预处理指令
#define 是C语言预处理指令之一。通过 #define 定义的常量在预处理阶段会被替换为其对应的值。
示例:
#define _CRT_SECURE_NO_WARNINGS
#define PI 3.14159
#include <stdio.h>
int main()
{
printf("%.5f\n", PI);
return 0;
}
输出结果:
在这个例子中,PI 是被定义为一个常量,它的值是3.14159。在程序中使用 PI 时,预处理器会将其替换为3.14159。
(2):const 关键字
const 关键字用于声明一个常量。与 #define 不同,const 声明的常量具有类型,因此编译器可以对其进行类型检查。
示例:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{
const float PI = 3.14159;
printf("%.5f\n", PI);
return 0;
}
这里的 PI 也是一个常量,其类型为 float,值为3.14159。
2.使用常量
定义了常量之后,就可以在程序中像使用变量一样使用它们了。
示例:
#define _CRT_SECURE_NO_WARNINGS
#define r 3
#include <stdio.h>
int main()
{
const float PI = 3.14159;
float area = PI * r * r;
printf("圆的面积 = %.2f\n", area); //%.2f可以理解为输出结果时保留两位小数
return 0;
}
输出结果:
在这个例子中,我们使用了 #define 定义的 r (即半径)常量和 const 定义的 PI (即圆周率)常量来计算圆的面积。
注意:在C语言中,一旦定义了一个常量(无论是使用 #define 预处理指令还是const 关键字),都不能直接给这个常量重新赋上新的值。
四、ASCII编码及转义字符
1.ASCII码的介绍
计算机中所有的数据(包括字符)都是以二进制的形式在内存中存储的。字符在内存中的具体表示是通过其对应的编码来实现的,其中最为基础和广泛使用的是美国国家标准学会(ANSI)制定的ASCII编码标准。C语言中的字符就遵循了ASCII编码的方式来表示和存储。
如果不方便找到上面的表,可以使用下面的代码来找
示例:
#include<stdio.h>
int main()
{
int i = 0;
//这是一个for循环,用于控制迭代过程。循环的初始条件是i=32,循环条件是i < 127
//(即当i小于127时继续循环),每次循环结束时i的值会增加1(i++)。
//这个循环会遍历ASCII码表中从32到126的所有值。
for (i = 32; i < 127; i++)
{
//在循环体内,使用printf函数打印当前i值对应的ASCII字符
//(%c格式指定符用于打印字符),并在字符后面打印一个空格。
printf("%c ", i);
//这段代码检查i是否是16的倍数减1(即,检查是否每打印了16个字符)。
//如果条件为真(即i % 16 == 15),则执行printf("\n");语句。
//打印一个换行符,以便每16个字符后开始新的一行。
if (i % 16 == 15)
{
printf("\n");
}
}
//循环结束后,这行代码再打印一个换行符,以确保在输出结束后有一个清晰的结束边界。
printf("\n");
return 0;
}
输出结果:
2.ASCII码的特点
我们不需要记住所有的ASCII码表中的数字,使用时查看就可以,不过建议最好能掌握几组特殊的数:
(1):大写字母 A~Z 的ASCII码值(65 - 90):
这些字符的ASCII码值从65开始,一直到90结束。例如,字符’A’的ASCII码是65,字符’Z’的ASCII码是90。
(2):小写字母 a~z 的ASCII码值(97 - 122):
这些字符的ASCII码值从97开始,一直到122结束。例如,字符’a’的ASCII码是97,字符’z’的ASCII码是122。
(3):大小写字符的ASCII码值差值(32):
对于任意一个大写字母和对应的小写字母,它们之间的ASCII码值相差32。例如,字符’A’(ASCII码65)和字符’a’(ASCII码97)之间的差值是32。
(4):数字字符 0~9 的ASCII码值(48 - 57):
这些字符的ASCII码值从48开始,一直到57结束。例如,字符’0’的ASCII码是48,字符’9’的ASCII码是57。
(5):换行符 \n 的ASCII值(10):
换行符的ASCII值是10。在文本文件中,换行符用于指示一行的结束并开始新的一行。
(6):不可打印字符(ASCII码值0~31):
这32个字符是不可打印字符,无法打印在屏幕上观察。
3.转义字符介绍
在C语言编程中,我们经常会遇到一些特殊的字符,它们无法直接通过键盘输入,或者它们具有在编程环境中特定的含义。为了表示这些字符,C语言引入了一种特殊的表示方法——转义字符(以反斜杠(\)作为前缀,后跟一个或多个特定的字符)。顾名思义,转义字符的作用就是“转变”或“逃逸”其后面字符的原始意义,以赋予它们新的、特定的含义。但下面的有些转义字符在编写代码不会经常使用,可了解一下。
(1):\n:换行符。在输出中,遇到 \n 时,光标会移动到下一行的开头。
(2):\t:水平制表符。通常用于在文本中创建水平间隔,等价于按下Tab键的效果。
(3):\:反斜杠字符本身。因为反斜杠被用作转义字符的引导符,所以如果要输出一个反斜杠,就需要使用两个反斜杠 \。
(4):‘:单引号字符。用于表示字符常量’。
(5):":双引号字符。用于表示一个字符串内部的双引号。
(6):\r:回车符。光标移到同一行的开头。
(7):\f:换页符。用于在打印时分隔页面,但在大多数文本处理环境中,它通常只作为普通字符处理。
(8):\a:警报,这会使得终端发出警报声或出现闪烁,或者两者同时发生。
(9):\b:退格符,光标回退⼀个字符,但不删除字符。
(10):\0:空字符(null 字符,代表没有内容)。在C语言中,字符串以空字符结尾。\0 是 \ddd 这类转义字符的⼀种。\0 实际上是字符常量中的字符值为0的字符,用于字符串的结束标志。
(11):\ddd(其中 ddd 是三位八进制数):表示一个特定的ASCII字符。例如,\141 表示ASCII码为十进制97的字符,即小写字母 ‘a’。
(12):\xhh(其中 hh 是两位十六进制数):同样表示一个特定的ASCII字符,但这次是使用十六进制表示。例如,\x61 也表示小写字母 ‘a’。
总结
通过本篇文章可以学习C语言的一些数据类型及相应的长度,其中解释了 signed 和 unsigned 的作用,还有一些变量和常量的使用及一些示例,最后还可以学习ASCII编码及转义字符的作用。
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)