铁汁们,大家好呀!最近都有好好学习吗?学习的铁汁们举个小爪爪呀。回头一看,脆皮来到这个平台分享知识已经一周啦!!这次的分享的学习内容是关于数据类型,变量,printf,scanf以及控制语句的内容。内容比较多,所以脆皮多花了一些时间学习以及记录笔记。
脆皮也是一个普通人,也会偶尔犯错,如果大家发现有什么错误之处,欢迎指正!大家可以在评论区多多互动呦!(哭唧唧:脆皮的评论区好冷清)
在没有更新的日子里,脆皮正在努力学习,大家也要加油喔!!
月饼模具----------用于制造月饼
类型就是模具----用于创建变量
一.数据类型
1.数据类型介绍
数据类型包括内置类型(C语言本身就具有)和自定义类型。
月饼模具----------用于制造月饼
类型就是模具----用于创建变量
- 内置类型包括:char,int,float,-Bool(今天所介绍的)
- 自定义类型包括:数组,结构体structural,枚举enum,联合体union(后期逐渐介绍)
(十进制)
类型 | 符号 |
---|---|
字符型(%c打印) | char(长度:1个字节) %c |
整型(%d打印) | 短整型short(2个字节)%hd |
整型int(4个字节)%d | |
长整型long int(4个字节)%ld | |
长长整型long long int(8个字节)%lld | |
浮点型(%f打印) | 单精度浮点型float(4个字节)%f |
双精度浮点型double(8个字节)%lf | |
long double(8个字节)%Lf | |
布尔类型(%d打印) | _Bool(1个字节) |
2.简单介绍一下布尔类型
sizeof(_Bool)= 1
C 语言原来并没有为布尔值单独设置⼀个类型,而是使用整数 0 表是假,非零值表示真。在 C99 中也引入了 布尔类型 ,是专门表示真假的。
布尔类型的使用得包含头文件 <stdbool.h>
布尔类型变量的取值是: true 或者 false (1或者0,所以用%d打印)
_Bool flag = true;
if (flag)
printf("i like C\n");
补充单位方面的知识:
3.补充介绍sizeof操作符
sizeof是专门用来计算(sizeof的操作符数的)类型长度,sizeof的返回值用%zd打印,单位是字节(1个字节=8个比特位)
- sizeof操作符的操作数可以是 :数据类型 / 表达式 / 变量
sizeof(类型) //注意:类型的括号一定不能省
sizeof 表达式 //变量或表达式可以省,但尽量写上
- sizeof中的表达式不计算。
#include<stdio.h>
int main()
{
int a = 9;
short b = 3;
printf("%d", sizeof(b = a + 2)); //最终的返回值是2
//前面定义b是short类型= a是int类型,2是int类型
//把int类型放在short里,最后结果谁说了算呢?整个表达式肯定是b说了算
//b的类型是short,所以最后的返回值是2
return 0;
}
所以这种,直接看s的类型就好
- sizeof针对类型和表达式,strlen针对字符和字符串,都是求长度
4.signed/unsigned+数据类型
signed和unsigned这两个关键字是用来修饰字符char和整型int的
-
signed (有符号)关键字:表示一个类型有正负
-
unsigned(无符号)关键字:表示一个类型没有负(0和正整数)
-
- int,默认带正负号,signed int=int,一般可以省略signed
- char,不确定是否带符号,取决于编译器的实现
-
使用unsigne的好处是:同样长度的内存能够表示的最大整数值增大了一倍。【16位的 signed short int 的取值范围是:-32768~32767,最大是32767;而unsigned short int 的取值范围是:0~65535,最大值增大到了65535。】
-
当使用了signed和unsigned,用什么打印也会改变
巧记: 有符号是%d,无符号是%u
类型 | 打印 |
---|---|
short int, unsigned short int | %hd, %hu |
int, unsigned int | %d, %u |
long int, unsigned long int | %ld, %lu |
long long int, unsigned long long int | %lld, %llu |
5.强制类型转换
语法形式:(类型)数字
万不得已才会使用强制转换
int a = 3.14;
//a的是int类型, 3.14是double类型,两边的类型不⼀致,编译器会报警告
int a = (int)3.14;
//意思是将3.14强制类型转换为int类型,这种强制类型转换只取整数部分,丢弃小数点后的
二.变量
1.介绍一下,变化的值称为变量,不变的值称为常量。
2.变量的创建及初始化:
//变量的创建:类型+变量名
int age;
char ch;
float weight;
//变量的初始化:就是在创建的时候给一个初始值
int age = 0;
char ch = 'q';
float weight = 121.5f//如果只写121.5,会被认为是double类型
//如果已经创建了变量,之后再等于某值,这是赋值
int age;
age = 29;//赋值
3.变量的分类:
全局变量(放在内存的静态区):在大括号外部定义的变量就是全局变量。使用范围更广,整个工程中想使用,都是有办法使用的。
局部变量(放在内存的栈区):在大括号里面定义的变量就是局部变量。适用范围比较局限,只能在自己所在的局部范围内使用。
#include <stdio.h>
int global = 2023;//全局变量
int main()
{
int local = 2018;//局部变量
}
4.如果全局变量和局部变量名字一样,局部优先使用
#include <stdio.h>
int local = 2023;//全局变量
int main()
{
int local = 2018;//局部变量
printf("local is %d", local);
return 0;
}
最后调试的结果是:local is 2018
三.操作符(又名运算符)
1.算术操作符(双目操作符)
1.算术操作符又叫做双目操作符,在操作符的两端分别有一个操作数,比如:a+b
2.算术操作符有五个:(+) (-) (*) (/) (%)
需要介绍的就是 / 和 % 了,其余的和数学中的一样。/ 是取商(操作数可以是浮点数), % 是取余(两端的操作数都必须时整数)。
3.注意事项:
- (1)/ 两端均是整数,则计算结果也是整数;只要有一端是小数,则结果就是小数。
- (2)C 语言里面的整数除法是整除,只会返回整数部分,小数部分会被丢弃。
#include<stdio.h>
int main()
{
float x = 6 / 4;
printf("%f", x);
//此处返回的x是1.0而不是1.5
return 0;
}
- (2)如果希望得到浮点数的结果,两个运算数必须至少有⼀个浮点数,这时 C 语言就会进行浮点数除法。
#include<stdio.h>
int main()
{
float x = 6.0 / 4;一个是浮点数
//float x =6.0 / 4.0;两个均是浮点数
printf("%f", x);
//这两种情况返回的x都是1.500000
return 0;
}
- (3)负数求模的规则是,结果的正负号由第⼀个运算数的正负号决定。
#include<stdio.h>
int main()
{
int a = 3 % 2; //a=1
int b = -3 % 2; //a=-1
int c = -3 % -2; //a=-1
printf("%d %d %d", a, b, c);
return 0;
}
2.赋值操作符(=)
在变量创建的时候给一个初始值叫初始化,在变量创建好后再给⼀个值,这叫赋值。
1.赋值
int a = 100;//初始化
a = 200;//赋值,这⾥使⽤的就是赋值操作符
2.连续赋值(不推荐)
c = b = a+3; --------连续赋值,从右向左依次赋值的。
3.复合赋值符(简便):+=,-=,*=,/=,%=
a += 3; // 也就是a = a + 3;
a %= 3; // 也就是a = a % 3;
3.单目操作符
C语言中还有一些操作符只有一个操作数,被称为单目操作符。 ++、- -、+(正)、-(负) 就是单目操作符的。
1.++和- -又分为前置和后置(原理相同,此处举例++)
- 前置++:先++,后使用
- 后置++:先使用,后++
int a = 0;
a = 5;
//如果单独使用,前后置的使用效果没有区别
a++; //a=6
++a; //a=6
//但如果赋值给别人就有区别了
int b = a--; //后置先使用,b=a=5,后减减a=a-1=5-1=4
int c = --a; //前置先减减,a=a-1=4,后使用c=新的a=4
- +(正):对值不会有任何影响
- -(负):与数学中的一样,正变负,负变正
4. 关系操作符(6个)
- ##(1)有哪些关系操作符
C 语言用于比较的表达式,称为 “关系表达式”,表达式里使用的运算符就称为“关系运算符”,主要有下面6个。(例子:‘a==b’是关系表达式,a和b是操作数,==是操作符)
> --------------大于运算符
< --------------小于运算符
>= ------------大于等于运算符
<= ------------小于等于运算符
== ------------相等运算符
!= -------------不相等运算符
此处需要特别注意的是,不要混淆相等运算符==和赋值运算符=
- ##(2)关系表达式返回什么
关系表达式的返回值是0或者1,表示真假。
C 语言中,0 表示假,所有非零值表示真。比如 ‘20 > 12’ 返回的是1 ,’ 12 > 2’ 返回的是0。关系表达式常⽤于 if 或 while 结构。
- ##(3)如何避免在使用关系操作符出错
- 此处需要特别注意的是,不要混淆相等运算符(两个等号用于判断是否相等)和赋值运算符(一个等号用于赋值),尤其是不要在if语句里用错
- if (x = 3)
上面示例中,原意是 x == 3,但是不小心写成 x = 3 【这个式子表示对变量 x 赋值 3 ,它的返回值为 3 ,所以 if 判断总是为真】
为了防止出现这种错误,可以在常量与变量比较时,将变量写在右边:if (3 == x)
- 另一个需要避免的错误是:多个关系运算符不宜连用(关系运算符是从左到右计算)
- i < j < k
在这个例子中,(1)会先比较i<j,看这个表达式对不对,若正确,则返回1;不正确,则返回0.(2)若返回1,则表达式变为1<k,接下来再进行判断。此处应该改为i<j && j<k
5. 条件操作符(又叫做三目操作符)
条件操作符也叫三⽬操作符,需要接受三个操作数,
形式如下:exp1 ? exp2 : exp3
。。。。。真。。结果
。。。。。假。。。。。结果
如果exp1为真,则exp2的计算结果是整个表达式的结果
如果exp1为假,则exp3的计算结果是整个表达式的结果
#include<stdio.h>
int main()
{
int a = 0; //int a = 0;
int b = 0; //int b = 0;
scanf("%d", &a); //scanf("%d", &a);
b = (a > 5 ? 3 : -3); //if (a > 5)
//b=后面表达式结果 // b = 3;
//如果a>5是真,则b=3 //else
// 是假,则b=-3 // b = -3;
printf("b=%d", b);
return 0;
}
6. 逻辑操作符(3个)
- ##(1)简介
- 逻辑取反运算符(!):用于改变单个表达式真假
------如果‘a’是假,则’!a‘是真
#include <stdio.h>
int main()
{
int flag = 0; //设变量flag是假
if (!flag) //则!flag是真
{
printf("do something\n");//所以此处可以打印
}
return 0;
}
- 逻辑与运算符(&&):简单来理解,就是‘并且’的意思。(a && b,若是&&两边的表达式都是真,整个表达式a && b才为真;两边有一个是假,则整体是假)
- 逻辑或运算符(||):即‘或者’的意思。(两边表达式有一个为真,即整体为真;两边全是假,则整体为假)
- 练习题:闰年的判断1
-##(2)短路
C语言逻辑运算符还有⼀个特点,它总是先对左侧的表达式求值,再对右边的表达式求值。仅仅根据左操作数的结果就能知道整个表达式的结果,不再对右操作数进行计算的运算称为短路求值。
- 对于&&操作符来说,左边操作数的结果是0的时候,则整体为假,右边操作数就不再执行。
- 对于 || 操作符来说,当左操作数的结果不为0时,则整体为真,无需执行右操作数。
- ##(3)运用时的难点
看清楚右边是否需要运算
#include<stdio.h>
int main()
{
int i = 0, a = 0, b = 2, c = 3, d = 4;
i = a++ && ++b && d++;
printf("i = %d\n a = %d\n b = %d\n c = %d\n d = %d\n", i,a, b, c, d);
return 0;
}
点击一下到最后的答案解释2.
7.赋值忽略符
有时,用户的输入可能不符合预定的格式。为了避免这种情况, scanf() 提供了一个赋值忽略符,只要把 * 加在任何占位符的百分号后面,该占位符就不会返回值,解析后将被丢弃。
#include<stdio.h>
int main()
{
int year = 0;
int month = 0;
int day = 0;
scanf("%d%*c%d%*c%d", &year, &month, &day);
return 0;
}
四.printf与scanf简介
1.printf基本简介已经在前面的篇章里介绍了,大家可以重温一下C语言概念
4.2printf中的占位符
1.printf()可以在输出文本中指定占位符,所谓 “占位符”,就是这个位置可以用其他值代入。(%+占位符类型) (例如%f)
%c , %d ,%f ,%lf , %Lf , %s 等等
2.输出文本中可以有多个占位符
3.printf() 参数与占位符是⼀⼀对应关系,如果有 n 个占位符, printf() 的参数就应该有 n +1 个。
#include <stdio.h>
int main()
{
printf("There are %d apples\n", 3);
//%d 就是占位符,表⽰这个位置要用后面的3来替换
printf("%s says it is %d o'clock\n", "lisi", 21);
//第一个占位符 第二个
printf("There are %d apples\n", 3);
//第一个参数(格式串) //第二个参数:3
return 0;
}
4.占位符举例:
4.3.printf()允许限定占位符的最小宽度和限定小数的位数。
5.1. 限定占位符的最小宽度(可限定整数和小数):%5d表示这个整数最少5位
- 默认右对齐,即如果只有3位数,则左边两位是空格。
如果想要左对齐,则在占位符的 % 的后面插入一个 - 号。例如:%-5d
5.2. 限定小数位数(限定浮点数%f):希望小数点后面只保留两位,占位符可以写成 %.2f
5.3. 两者可同时限定:例如最小宽度为12,小数点后的位数是3,则写为%12.3f
5.4. 最小宽度和小数位数这两个限定值,都可以用 * 代替,通过 printf() 的参数传入,例如
printf("%*.*f\n", 12, 3, 0.5);
输出结果是- - - - - - -0.500
4.4使printf输出的数字显示正负号
默认情况下, printf() 不对正数显示 + 号,只对负数显示 - 号,如果想让正数也输出 + 号,可以在占位符的 % 后面加⼀个 + 。 %+d 可以确保输出的数值,总是带有正负号。
4.5 输出部分字符串
如果只想输出开头的部分,可以用 %.[长度]s 指定输出的长度,例如:printf("%.5s\n", "hello world");
输出结果是hello
4.5 scanf
4.5.1 简介
scanf() 函数用于读取用户的键盘输入。程序运行到这个语句时,会停下来,等待用户从键盘输入。用户输入数据、按下回车键后, scanf() 就会处理用户的输入,将其存入变量。它的原型定义在头文件 stdio.h 。scanf() 的语法跟 printf() 类似。(一定一定要记得写取地址符&,指针变量除外。因为 scanf() 传递的不是值,而是地址,即将变量 i 的地址指向用户输入的值。)
scanf("%d", &i);
上面示例中, scanf() 的第一个参数 %d ,表示用户输入的应该是一个整数。 %d 就是⼀个占位符。第二个参数 &i 表示,将用户从键盘输入的整数存入变量i 。
- scanf() 处理数值占位符时,%c不会忽略空白字符(总是返回当前第一个字符,无论该字符是否为空格)。【如果要强制跳过字符前的空白字符,可以写成
scanf(" %c", &ch)
,即 %c 前加上⼀个空格,表示跳过零个或多个空白字符。】其余的,如%d,%f等等会自动过滤空白字符(包括空格、制表符、换行符等。),所以,当占位符是除了%c之外的,有一个或多个空格不影响 scanf() 解读数据
int main()
{
char ch,sh;
scanf("%c", &ch);
printf("xx%cxxx\n", ch);
return 0;
}
需要特别注意的是:%s
- scanf() 处理用户输入的原理是,用户的输入先放入缓存,等到按下回车键后,按照占位符对缓存进行解读。
解读用户输入时,会从上次解读遗留的第一个字符开始,直到读完缓存,或者遇到第一个不符合条件的字符为止。
先取%d,得到-13,之后%f,遇见了.45e12,取不了# 0
4.5.2. scanf的返回值
1.scanf() 的返回值是一个整数,表示成功读取的变量个数。
- 如果没有读取任何项,或者匹配失败,则返回 0
- 如果在成功读取任何数据之前(还没有输入任何数字),发生了读取错误或者遇到读取到文件结尾(三次ctrl z),则返回常量 EOF (-1)。【EOF - end of file 文件结束标志】
- 格式一定要匹配:scanf(“%d %d”,&a,&b);
- 则从键盘输入,一定要数字 空格 数字
- scanf(“%d,%d”,&a,&b)输入数字 逗号 数字
2.经常用scanf()的返回值判断是否读取成功,如果返回的是EOF,则读取失败;反之,读取成功。
3.scanf()的占位符和printf()相似:%c , %d ,%f ,%lf , %Lf , %s ,%[ ]这个是匹配数字字符(比如 %[0-9] ),遇到不在集合之中的字符,匹配将会停止)
4.scanf()的占位符中,%c不会忽略空白字符,总是返回当前第一个字符,无论该字符是否为空格。其余的,比如%d,%f会忽略空白字符
五.选择语句
1. if语句
##1.1 if
- 1.语法形式:
if(表达式,即判断条件) if() if()
语句(即想要执行的东西) 语句 {语句
语句
}
如果if后执行的语句不止一条,则用{ }将语句括起来(后面的else同理)
使用{ }控制多条语句-这个块也叫:程序块,或者复合语句
- 2.表达式为真,则执行语句;表达式为假,不执行。eg:
if(1==2) //这里让判断1和2是否相等,若相等,则表达式为真,输出'两者相等'
printf("两者相等"); //但很明显,1,2不相等,表达式为假,不执行语句
##1.2 if…else
if( ) //如果....
语句 // 则....
else //否则
语句 // 则...
##1.3嵌套if
if(num == 0)
printf(" ");
else if(num > 0) //这⾥的if 相当于嵌套在else语句中,形成了嵌套结构
printf(" ");
else
printf(" ");
if (num > 0)
{
if (num % 2 == 0)
printf("偶数\n");
else
printf("奇数\n");
}
else
{
printf("⾮正数\n");
}
## 1.4悬空else
如果有多个 if 和 else ,可以记住这样一条规则, else 总是跟最接近的 if 匹配。
此图中,else与if(b==2)匹配,但是a!=1,刚开始就根本没有进入循环,更别说后边。最后结果:什么也没有打印。
只要带上适当的⼤括号,代码的逻辑就会更加的清晰
2. switch语句
在判断条件有多个结果的情况下,使用switch更方便。
switch (表达式)
{
case value1:
printf(" ");
(有无break均可)
case value2:
printf(" ");
(有无break均可)
default:
printf(" ");
(有无break均可)
}
- break(跳出switch语句,不一定每个case语句都有):如果某⼀个case语句后面没有break语句,代码会继续往下执行,可能执行其他case语句中的代码,直到遇到break语句或者switch语句结束。
3.default(有无均可):
switch后的表达式的值,与所有的case均不匹配,可以选择将这种情况放入default
default:
printf("输⼊错误\n");
break;
switch例子:
//输⼊⼀个1~7的数字,打印对应的星期⼏
#include <stdio.h>
int main()
{
int day = 0;
scanf("%d", &day);
switch (day)
{
case 1:
printf("星期⼀\n");
break; //如果没有break,输入1,则会打印出星期一到星期日
case 2: //break是用来跳出switch语句的
printf("星期⼆\n");
break;
case 3:
printf("星期三\n");
break;
case 4:
printf("星期四\n");
break;
case 5:
printf("星期五\n");
break;
case 6:
printf("星期六\n");
break;
case 7:
printf("星期天\n");
break;
}
return 0;
}
六.循环语句
1. for循环(先判断)
int a = 0; //还是需要先引出来变量的
for(1.初始化表达式;2.判断表达式;4.调整) //中间用;隔开
3.语句; //for括号后没有;
顺序:1----2(为真)----表达语句3-----进行调整4-----再判断2(如果还是真)—表达语句3-------4--------2(循环,直至判断为假,跳出循环)
练习题:计算1~100之间3的倍数的数字之和1
2. while循环(先判断)
while(表达式)
语句;//如果循环体想包含更多的语句,可以加上⼤括号
- 判断表达式,如果表达式的值=0,则为假,不进入循环;值为非0,则为真,进入循环。
- while后面有多条语句,用大括号{ }
- if和while的区别:
if后边条件满足,打印一次hehe
while后边的条件满足,死循环的打印hehe
3. do-while循环(先执行一次再判断)
do-while在循环中使用的最少
- 不管是否满足条件,都会先执行一次。先执行语句,再去执行“判断表达式”(判断表达式的结果是!=0,则继续循环,执行循环语句;判断表达式的结果==0,则循环结束)
补充 break和continue语句
- break是用于永久的终止循环,直接跳出循环。在三种循环中都一样。
- continue是跳过本次循环中 continue 后边的代码,继续进行下一次循环的判断。在 for 循环和 while 循环中有所差异的。(for循环的continue不会跳过调整部分,while不一定【具体看调整部分的位置】,如果循环的调整是在 continue 后边的话,可能会造成死循环)
10. 循环的嵌套
三种循环往往会嵌套在⼀起才能更好的解决问题
练习:找出100~200之间的素数,并打印在屏幕上。(注:素数又称质数,只能被1和本身整除的数字)
11. goto语句
goto 语句可以实现在同⼀个函数内跳转到设置好的标号处。
printf("haha\n");
printf("bubu\n");//最终打印结果是haha
return 0; // bubu
int main()
{
printf("haha\n");
if (1)
goto end; //在此处的时候,跳转到后面的end那里了
printf("bubu\n"); //最终结果:haha
end: // 没想到吧
printf("没想到吧\n");
return 0;
}