文章目录
前言
在了解完C语言学习的前提知识后,下面我们将详细地讲解C语言的内容,
我将由易到难、由简到繁带大家串完C语言。
一、数据类型
在生活中,我们会说很多的数据3.14,123,324...
C语言提供了丰富的数据类型来描述生活中的各种数据。
使用整型类型来描述整数,使用字符类型来描述字符,使用浮点型类型来描述小数。所谓“类型”,就是相似的数据所拥有的共同特征,编译器只有知道了数据的类型,才知道怎么操作数据。
C语言的数据类型分为两类:
- 自定义类型(由我们自己定义)
- 内置类型(C语言提供)
如图:
为了循序渐进的学习,本章节主要探讨内置类型的使用。
1.整形
//短整型
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]
2.浮点型
float
double
long double//不常用
float
是单精度浮点型,double
是双精度浮点型。
int main() {
float f = 0.123456789f;
double d = 0.123456789;
printf("float: %.15f\n", f); // 打印float类型,期望15位小数
printf("double: %.15lf\n", d); // 打印double类型,期望15位小数
return 0;
}
output:
float: 0.123456791043282
//可以发现float类型数据在小数点后9位的数字是随机生成的
double: 0.123456789000000
//而double类型数据后面则会补零
因此,double
的精度会更高。
3.字符型
char
[signed] char
unsigned char
在上一期的文章中,我们简单介绍了字符,而字符的类型就是char
例如,我们可以这样类比:
123是整形,即int
类型的;
‘a’是字符,是char
类型的。
4.布尔型
C 语言原来并没有为布尔值单独设置一个类型,而是使用整数 0 表示假,非零值表示真
。
在 C99 中也引入了布尔类型 ,是专门表示真假的。
_Bool
布尔类型的使用得包含头文件 <stdbool.h>
布尔类型变量的取值是:true
或者false
_Bool bool = true;
二、数据类型的对比
我们发现,对于整形来说,竟然划分出int,short,long,long long
四种类型,可以猜测即使是同一类型,也有很多不同之处,下面我们来进行比较。
1.数据类型的长度
数据类型的长度决定了其取值范围,我们可以使用sizeof
操作符来计算长度。
sizeof 是一个关键字,也是操作符,专门是用来计算sizeof操作符数的类型长度的,
单位是字节
。
字节是什么呢?
字节(Byte)是计算机信息技术中用于计量存储容量和数据传输的基本单位。一个字节由8个二进制位(bits)组成,每个位可以是0或1
说起存储容量单位,我们会联想到手机内存是256GB,没有错,GB也是这样的单位,换算规律如下:
1字节(Byte)=8字位=8个二进制数
1字位(bit)=1个二进制数
1Byte=8bit
1KB=1024B
1MB=1024KB
1GB=1024MB
sizeof 操作符的操作数可以是类型,也可是变量或者表达式。
sizeof(类型);
sizeof(表达式);
//后边的表达式是不真实参与运算的,根据表达式的类型来得出⼤小。
所以,我们写下这样的程序:
#include <stdio.h>
int main()
{
printf("%zd\n", sizeof(char));
printf("%zd\n", sizeof(_Bool));
printf("%zd\n", sizeof(short));
printf("%zd\n", sizeof(int));
printf("%zd\n", sizeof(long));
printf("%zd\n", sizeof(long long));
printf("%zd\n", sizeof(float));
printf("%zd\n", sizeof(double));
printf("%zd\n", sizeof(long double));
return 0;
}
在VS2022 X64
配置下的输出:
1
1
2
4
4
8
4
8
8
2.signed和unsigned
细心的同学会发现,为什么会有signed char和unsigned char
C 语言使用 signed 和 unsigned 关键字修饰字符型和整型类型。
signed 关键字,表示一个类型带有正负号,包含负值;
unsigned 关键字,表示该类型不带有正负号,只能表示零和正整数。
- 对于 int 类型:
默认是带有正负号的,也就是说 int 等同于 signed int 。
由于这是默认情况,关键字 signed 一般都省略不写,但是写了也不算错。
int 类型也可以不带正负号,只表示非负整数。这时就必须使用关键字unsigned 声明变量。
signed int a;
//=int a;
unsigned int b;
- 对于 char 类型:
C 语言规定 char 类型默认是否带有正负号,由当前系统决定。
这就是说, char 不等同于 signed char ,它有可能是 signed char ,也有可能是unsigned char 。
signed char c; // 范围为 -128 到 127
unsigned char c; // 范围为 0 到 255
3.取值范围
上述的数据类型很多,尤其数整型类型就有short、int、long、long long
四种,为什么呢?
其实每⼀种数据类型有自己的取值范围,也就是存储的数值的最⼤值和最小值的区间,有了丰富的类型,我们就可以在适当的场景下去选择适合的类型。如果要查看当前系统上不同数据类型的极限值:
limits.h
文件中说明了整型类型的取值范围。
float.h
这个头文件中说明浮点型类型的取值范围。
为了代码的可移植性,需要知道某种整数类型的极限值时,应该尽量使用这些常量。
• 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 的最大值。
举个例子:
就看到一些整形的取值范围了(如图),浮点型的操作方式类似,大家感兴趣可以试一试。
三、变量
了解清楚了类型,我们使用类型做什么呢?类型是用来创建变量的。
什么是变量呢?C语言中把经常变化的值称为变量,不变的值称为常量
。
1.变量的创建
变量的创建形式:
data_type name;
| |
| |
数据类型 变量名
int age; //整型变量
char ch; //字符变量
double weight; //浮点型变量
变量名的命名:
变量名属于标识符(标识符是程序员为变量、函数、数组、类、模块等编程实体自定义的名称),所以我们直接学习一下表示符的命名规则:
- 字母数字组成:标识符通常以字母(a-z,A-Z)或下划线(_)开头,后面可以跟字母、数字(0-9)或下划线。
- 区分大小写:多数编程语言中,标识符是区分大小写的,即myVariable和MyVariable被视为两个不同的标识符。
- 避免使用关键字:标识符不能与关键字相同。
关键字如常见的if、else、while、for、return、int
变量在创建的时候就给一个初始值,就叫初始化。
data_type name = Initial value;
| | |
| | |
数据类型 变量名 初始值
int age = 18;
char ch = 'w';
double weight = 48.0;
unsigned int height = 100;
2.变量的分类
• 全局变量:在大括号外部定义的变量就是全局变量
全局变量的使用范围更广,整个工程中想使用,都是有办法使用的。
• 局部变量:在大括号内部定义的变量就是局部变量
局部变量的使用范围是比较局限,只能在自己所在的局部范围内使用的。
#include <stdio.h>
int global = 2023;//全局变量
int main()
{
int local = 2018;//局部变量
printf("%d\n", local);
printf("%d\n", global);
return 0;
}
如果全局变量和局部变量名字相同呢?
#include <stdio.h>
int n = 1000;//全局变量
int main()
{
int n = 10;//局部变量
printf("%d\n" ,n);//打印的结果是多少呢?
return 0;
}
最终打印10,所以当局部变量和全局变量同名的时候,局部变量优先使用。
但是我们还是要避免这种同名情况。
3.常量
常量就是值不可被改变的,在将某个定义为常量之后,它的值是不可被改变的。在C语言当中有四种常量类型。
分别是:
1 字面常量
2 const修饰的常变量
3 #define定义的标识符常量
4 枚举常量
字面常量就是直接写出来的
123; //这样直接写出来的就是字面常量
'abc';
const修饰的常变量
const 关键字用于声明只读变量,即其值在初始化后不能被修改的变量
const double PI = 3.14;
#define定义的标识符常量就是通过 #define 定义,一般使用大写字母
#define PI 3.14
因为生活中有些东西是不变的,所以就可以用到枚举,要使用到枚举关键字enum
enum Sex //因为有些东西是不变的 所以就定义为枚举常量
{
MALE,
FAMALE,
SECRET
};
四、指针基础
指针是C语言学习的重难点,本文主要讲解指针的基础,后期会展开讲解。
1.地址
比如:某天你想去朋友家玩,是不是要先知道xx小区xx楼xx层xx门牌号,然后找到TA家。这种方式找地址
的方式最为快捷。
其实,在计算机中也有类似的处理(会在指针章节详解)
在C语言中创建变量其实就是向内存申请空间,然后得到一个地址。
int a = 10;//向内存申请空间
上述的代码就是创建了整型变量a,内存中申请4个字节,用于存放整数10,其中每个字节都有地址,上图中4个字节的地址分别是:
0x006FFD70
0x006FFD71
0x006FFD72
0x006FFD73
那我们如何能得到a的地址呢?
这里就得学一个操作符(&
)取地址操作符
int a = 10;
printf("%p\n", &a);//%p占位符打印地址,&a取出a的地址
那我们通过取地址操作符(&)拿到的地址是一个数值,比如:0x006FFD70
,这个数值有时候也是需要存储起来,方便后期再使用的,那我们把这样的地址值存放在哪里呢?答案是:指针变量。
2.指针
int a = 10;
int* pa = &a;//取出a的地址并存储到指针变量pa中
指针变量也是一种变量,这种变量就是用来存放地址的,存放在指针变量中的值都会理解为地址。
这里pa左边写的是 int* , *
是在说明pa是指针变量,而前面的 int 是在说明pa指向的是整型(int)类型的对象。
如果有⼀个char类型的变量ch,ch的地址,要放在什么类型的指针变量中呢?那就是char*
了
3.解引用操作符
我们将地址保存起来,未来是要使用的,那怎么使用呢?
我们只要拿到了地址(指针),就可以通过地址(指针)找到地址(指针)
指向的对象,这里必须学习⼀个操作符叫解引用操作符(*)
。
int main()
{
int a = 100;
printf("%d ",a);
int* pa = &a;
*pa = 0;
printf("%d ",a);
return 0;
}
上面代码中pa中存储a的地址,再通过解引用操作(*)pa变为0(此时pa = a),使a数值发生变化。
那么结果就是:
100 0
五、总结
通过这次的讲解,我们要学会正确地使用数据类型来创建变量,变量是程序中最基础的构成,所以本期非常重要。接下来,我会继续更新,下期更精彩哦。
关注我,带你学习C语言!o( ̄▽ ̄)o🎉
完