本人习惯于使用Markdown进行笔记记录,因此,此篇博客内容是从我的Markdown笔记中直接复制粘贴而来,针对因复制粘贴而产生的格式和字体颜色问题,我已对其进行了相应调整。若在阅读过程中,读者发现字体颜色或排版仍存在任何不当之处,敬请谅解。若读者在阅读笔记时,发现其中存在理论方面的谬误或不足,恳请不吝赐教,批评指正!小生定当虚心受教。
一、内置类型
(一)字符型
1. char //character
2. [signed] char
3. unsighed char
(二)整型
短整型
1. short [int] 2. [signed] short [int] 3. unsigned short [int]
整型
1. int 2. [signed] int //有符号的,矢量,既可能存正数也可能存复数(signed int == int) 3. unsigned int //无符号的,标量,只能存0和正数
长整型
1. long [int] 2. [signed] long [int] 3. unsigned long [int]
更长的整型
1. long long [int] 2. [signed] long long [int] 3. unsigned long long [int]
(三)浮点型
1. float
2. double
3. long double
(四)布尔类型
//布尔类型的使用要包含头文件 #include<stdbool.h>
//布尔类型变量的取值是:true或者false
1. _Bool
2. bool
二、自定义类型
自定义类型这里先不进行学习
三、各种数据类型的大小(sizeof()
)
(一)数据类型大小是什么意思?
每⼀种数据类型都有自己的大小,使用不同的数据类型,能够创建出大小不同的变量,变量大小的不同,存储的数据范围就有所差异。我们合理的使用不同数据类型去声明变量,可以节省存储空间。
(二)语法结构
sizeof(数据类型)
sizeof 表达式
————————————————————————————————实例————————————————————————————————
#include <stdio.h>
int main()
{
int a = 1;
printf("%zd" , sizeof(a));
return 0;
}
//输出结果:4
——————————————————或——————————————————
#include <stdio.h>
int main()
{
printf("%zd", sizeof(int));
return 0;
}
//输出结果:4
(三)sizeof()
中不计算表达式
sizeof( )这个操作符是用来求数据类型大小的,特别要注意的是sizeof( )括号中如果出现表达式,sizeof( )是不会去计算表达式的,但是仍然会返回数值
代码演示:
#include <stdio.h>
int main()
{
int a = 1;
int b = 2;
short c = 0;
printf("%zd", sizeof(c = a + b));
return 0;
}
//输出结果:2
//解释:此处a变量和b变量是int声明的(4byte),c变量是short声明的(2byte),int变量加int变量得到的变量应为同样的int类型 输出的结果应该为4,但是sizeof( )不计算表达式,只是单纯求数据类型大小,而c变量的数据类型大小为2byte,所以输出结果为2
四、signed和unsigned的区别以及区分signed和unsigned的好处
(一)区别
signed可以理解为矢量,既可能存正数也可能存负数(signed int == int)
unsigned可以理解为标量,只能存0和正数
(二)好处
16位的 signed short int 的取值范围是:-32768~32767,最⼤是32767;⽽unsigned short int 的取值范围是:0~65535,最⼤值增⼤到了65535。简言之就是可以扩大正数的取值范围,如果我们确定了变量一定为正数,我们可以使用unsigned
五、变量
(一)创建变量
1.语法结构
数据类型 变量名;
//变量创建的本质:向内存申请一个空间,空间的大小取决于数据类型
(二)变量的分类:全局变量和局部变量
1.代码解释
int a = 1; //全局变量
int main()
{
{
int b = 2; //局部变量
}
return 0;
}
2.全局变量和局部变量的使用原则
能使用局部变量尽量使用局部变量,必须使用全局变量的时候使用全局变量;
当局部变量和全局变量同名的时候,局部变量优先使⽤;
全局变量没有初始化时,默认为0
局部变量没有初始化时,默认为随机数(在VS2022IDE中,局部变量不初始化就会报错);
六、操作符
(一)算数操作符
- 加,
+
- 减,
-
- 乘,
*
- 除,
/
- 求模,
%
1.除,/
小问题:
#include <stdio.h>
int main()
{
float x = 6 / 4;
int y = 6 / 4;
printf("%f\n", x); // 输出 1.000000
printf("%d\n", y); // 输出 1
return 0;
}
我们发现,不管使用%f
打印还是使用%d
打印,最终输出结果都是1,而根据数学逻辑来看,输出结果应该为1.5
出现这种情况的原因是C语言除法运算规则:除号的两端如果是整数,执⾏的是整数除法,得到的结果也是整数;除号的两端如果存在浮点数,执⾏的是浮点数除法,得到的结果也就是浮点数。
解决:
#include <stdio.h>
int main()
{
float a = 6.0;
int b = 4;
printf("%f", a / b);
return 0;
//输出结果:1.500000
}
2.求模,%
(1)说明
运算符 % 表⽰求模(余)运算,即返回两个整数相除的余值。这个运算符只能⽤于整数,不能⽤于浮点数。
(2)负数求模
负数求模的规则是,结果的正负号由第⼀个运算数的正负号决定。
代码说明:
#include <stdio.h>
int main()
{
printf("%d\n", 11 % -5); // 输出:1
printf("%d\n",-11 % -5); // 输出:-1
printf("%d\n",-11 % 5); // 输出:-1
return 0;
}
(二)赋值操作符
在变量创建好之后,我们再给他一个值,这就是赋值
1.连续赋值
代码演示:
int a = 3;
int b = 5;
int c = 0;
c = b = a+3;
2.复合赋值
代码演示:
int a = 10;
a = a+3;
a = a-2;
—————————或者—————————
int a = 10;
a += 3;
a -= 3;
(三)单目操作符
++
--
+
(正数)-
(负数)
1.++
和--
(自增和自减)
(1)++a
前置++,先自加1,再参与代码
代码解释:
int a = 10;
int b = ++a;
printf("a=%d b=%d\n",a , b);
//输出结果:a=11 b=11
(2)a++
后置++,先参与代码,再自加1
代码解释:
int a = 10;
int b = a++;
printf("a=%d b=%d\n",a , b);
//输出结果:a=11 b=10
(3)--a
前置--,先自减1,再参与代码
(4)a--
后置--,先参与代码,再自减1
七、强制类型转换
(一)语法结构
(类型)对象; ——————实例——————
#include <stdio.h> int main() { int a = (int)123.456; //这里把123.456强行变成了整型123 printf("%d", a); return 0; } //输出结果:123
八、scanf
和printf
(一)printf
1.介绍
printf
是用来输出结果的语句,我们如果想使用printf,必须引用stdio.h
(standard input ouput)这个头文件
2.占位符
(1) 什么是占位符
所谓 “占位符”,就是这个位置可以⽤其他值代⼊
代码解释
#include <stdio.h>
int main()
{
int a = 10;
int b = 20;
printf("小明今年%d岁,小刚今年%d岁。", a, b); // 这里a和b的数值按顺序填充到了前面的占位符里面,一个萝卜一个坑
}
//输出结果:小明今年10岁,小刚今年20岁。
(2) 常见的占位符
不同的占位符对应不同的数据类型
-
%c
字符 -
%d
十进制整型 -
%f
小数 -
%hd
十进制short int
类型 -
%hu
unsigned short int
类型 -
%ld
十进制long int
类型 -
%lu
unsigned long int
类型 -
%Lf
long double
类型浮点数 -
%p
指针(⽤来打印地址) -
%s
字符串 -
%u
unsigned int
⽆符号整数 -
%x
⼗六进制整数 -
%zd
size_t
类型 -
%%
输出⼀个百分号
3.输出格式
printf()
可以定制占位符的输出格式
(1)限定输出宽度
代码演示:
#include <stdio.h>
int main()
{
printf("%5d\n", 123); // 输出为 " 123"
return 0;
}
//输出结果:__123
//解释:123前面有两个空格,原因是要求输出5位的长度,前面自动补了两个空格
#include <stdio.h>
int main()
{
printf("%-5d\n", 123); // 输出为 " 123"
return 0;
}
//输出结果:123__
//解释:123后面有两个空格,空格在后面的原因是把5变成了-5,变成了左对齐,所以在123后面补了两个空格
(2)总是显示正负号
代码演示:
#include <stdio.h>
int main()
{
printf("%+d\n", 12); // 输出 +12
printf("%+d\n", -12); // 输出 -12
return 0;
}
(3)限定小数位数
代码演示:
#include <stdio.h>
int main()
{
printf("%.2f\n", 0.579);
return 0;
}
//输出结果:0.58
//不仅可以限定小数位数,还会自动四舍五入
(4)输出部分字符串
代码演示:
#include <stdio.h>
int main()
{
printf("%.5s\n", "hello world");
return 0;
}
//输出结果:hello
//说明:%.5s代表输出字符串前五位
(二)scanf
1.介绍
printf
是用来输出的,那么scanf
就是用来输入的,如果我们想使用scanf
那么我们必须在源文件第一行输入 #define _CRT_SECURE_NO_WARNINGS 1
,同时也要包含头文件stdio.h
代码演示:
#include <stdio.h>
int main()
{
int score = 0;
printf("请输⼊成绩:");
scanf("%d", &score);
printf("成绩是:%d\n", score);
return 0;
}
//如果我们输入100,那么输出结果:
请输入成绩:100
成绩是:100
2.使用scanf
(1)语法结构
scanf("占位符", &将被赋值的变量);
——————例子——————
scanf("%d%d%f%f", &i, &j, &x, &y);
//i、j将被赋整型变量,x、y将被赋浮点型变量,我们输入什么数值,i、j、x、y就会被赋予什么数值
//scanf() 处理数值占位符时,会⾃动过滤空⽩字符,包括空格、制表符、换⾏符等。所以,用户输⼊的数据之间,有⼀个或多个空格不影响 scanf() 解读数据。另外,用户使⽤回⻋键,将输⼊分成⼏⾏,也不影响解读。
3.剖析scanf
第一个参数是格式字符串,里面要放置占位符,占位符的作用是告诉IDE马上用什么数据类型解读输入的参数
第⼆个参数
&i
表⽰,将⽤户从键盘输⼊的整数存⼊变量 i。&
是取地址符,如果这⾥的变量是指针变量(⽐如字符串变量),那就不⽤加&
运算符。
scanf
是有返回值的,返回值是int类型,返回的是成功读取的变量的个数,如果没有读取任何项,或者匹配失败,则返回0 ,如果在成功读取任何数据之前,发⽣了读取错误或者遇到读取到⽂件结尾,则返回常量 EOF (-1)。
4.scanf
的占位符
scanf
的占位符和printf
一样,但是也有特殊情况
(1) %c
特殊情况
除了 %c
占位符之外,都会⾃动忽略起⾸的空⽩字符。%c
不忽略空⽩字符总是返回当前第⼀个字符,⽆论该字符是否为空格。如果要强制跳过空白字符,可以写成scanf(" %c", &a);
,*即在%c
前面加上一个空格
4.scanf
的赋值忽略符
赋值忽略符针对用户的输入可能不符合预定的格式
比如说:
#include <stdio.h>
int main()
{
int year = 0;
int month = 0;
int day = 0;
scanf("%d-%d-%d", &year, &month, &day);
printf("%d %d %d\n", year, month, day);
return 0;
}
上面这串代码想让用户输入年月日,并通过 “年-月-日” 的格式打印出来,但是如果用户输入 “年 月 日” 的格式,程序会出现问题,因为 scanf
解读int类型的变量时遇到了字符型的数据,导致解读失败。
为了避免这样的情况,我们可以采用以下代码:
# include <stdio.h>
int main()
{
int year = 0;
int month = 0;
int day = 0;
scanf("%d%*c%d%*c%d", &year, &month, &day); //在占位符%和c之间加上星号(*)
return 0;
}
// 解释:虽然scanf解读到了字符型数据,但是因为我们使用了赋值忽略符,所以scanf抛弃了该字符,继续解读下一个