目录
4.数据类型
4.1字符型数据
4.1.1字符型常量
4.1.2字符型变量
4.2整型数据
4.3浮点型型数据
5.数据运算
5.1算数运算
5.2算数运算
5.3 “++”自增运算符和“–”自减运算符
5.4位运算
5.5复合运算符
6.格式输入输出
6.1格式输出
6.2格式输入
6.3其它输入输入
1.C语言概述
一句话就是人和计算机交流的语言,至于它的用途我会在后面更新嵌入式的应用,先打好C语言基础,学习后面嵌入式的内容不是问题。
2.第一个程序
#include <stdio.h>//编译预处理命令
int main() //主函数
{
printf("Hello word!\n");
return 0;//函数返回值
}
该程序运行结果
#include<stdio.h> 作用是告诉C语言编译器,“我”要预先处理一些事情。什么事情呢?
#include 表示导入一个(也翻译为包含) ,std -标准库,i-intput(输入),o-output(输出).h - 头文件,<> - 系统文件 。“我”要导入一个标准库的输入输出系统头文件。
为什么要提前预处理?
printf(); 格式输出函数,它是被包含在#include <stdio.h>里面的,没有这个头文件编译器在编译时会报错,程序也无法运行。
int main()
这是一个主函数,它是程序的入口,程序运行时会从它后面的大括号里面开始运行程序。
printf();
格式输出函数,它的作用就是将括号里面的内容输出到屏幕上。
return 0;
函数返回值,一个函数运行完成时,会返回一个值,这个值是多少有自己定。
// 和 /**/
// 这是用于解释一行代码 ,编译时不会编译到程序里面。/**/用于多行解释 ,/ * 用要注释的开头,* /用于注释的结尾。同样也不会编译到程序里面
\n
是转义字符换行符。(后面会讲)
写代码时,注意除了汉字,字符串里面的内容可以由中文符号。其余所有符号均在英文状态下进行书写。
3.变量和常量
3.1变量
什么是变量,生活中有些值一直在变,比如时间,你微信余额。在程序运行过程中可以改变的值,我们称为变量。( 注意变量在使用时一定要先定义)
如何定义变量?
先说明一下,变量有四要素:
1.数据类型
2.变量名
3.变量值
4.存储单元
如何定义变量
比如 int a = 3;
int 表示数据类型,变量名是a,变量值是3,存储单元也就是存储地址计算机会自动分配。
变量名a为合法的C语言标志符,标志符就是一个名字。我们在后面学习到的数组,结构体,函数等,都需要命名(标识符)。
C语言标识符满足以下规则:
1.只能由字母(包括大写和小写)、数字和下划线( _ )组成。
2.不能以数字开头。
3.变量名不能使用关键字。
常变量const
我们在变量前加一个const,这样变量的值不能改变。
比如const int a = 3;
那么a的值不能改变
#include <stdio.h>
int main()
{
const int a = 3;
a = 1;
printf("%d",a);
return 0;
}
编译时会出现这样的错误
3.2常量
我们上面讲了变量,常量是很什么,大家心里应该知道了。就是程序运行过程中不变的值
比如:
#include <stdio.h>
#define PI 500
int main()
{
printf("%d\n",PI);
return 0;
}
运行结果
500
定义规则也是简单
#define <符号常量名> <字符序列>
注意要求:
1.不在主函数里面定义
2.符号常量名通常大写
4.数据类型
在变量那举了个例子,学校有不同类型的教室,方便学生上课。比如美术生去上素描,要去美术室,要去上C语言我要去微机室。把这些教室看成数据类型,这些教室上的课就是一些数据,不同的类型教室处理不同的课程。同样的在C语言里有不同的数据类型来处理数据。
C语言数据类型可分为如下所示:
是不是看个很头大,不用担心我们现在只需要知道字符型,整型数,浮点类型就行了。
4.1字符型数据
单个符号的表示在c语言中划分为字符型数据。字符型数据在代码中通常表现为字符型常量或字符型变量。
4.1.1字符型常量
单引号括起来的单个字符,称为字符常量。例如:‘a’,‘X’,‘1’等。C语言还有一 种特殊形式的字符常量,即转义字符型常量。常用的以“\”开头的转义字。
常用转义字符常量如下图所示:
![在这里插入图片描述](https://img-blog.csdnimg.cn/953328049f7c4917b8ac09a4473931ec.png)
字符在内存中按其代码(整数)形式存储的,该整数值称为字符的ASCII编码值,ASCII表大家百度可以查询。C语言把字符型数据作为整数类型的一种,整数和字符可进行运算。
注意:
1.字符常量需用时要用单引号括起来,不能用双引号或其他括号。在第一个程序里提到大家可以去看看程序里\n是在单引号内。
2.'1’和1相加时不是等于2,‘1’需要转换为对应的ASCII值来参与运算,ASCII表大家百度可以查询。
4.1.2字符型变量
字符变量可以看作是整型变量的一种,它的标识符为“char”。
怎么定义? 例如:char data = ‘A’;
代码如下所示:
#include <stdio.h>
int main()
{
char data = 'A';
printf("%d %c\n",data,data);
return 0;
}
运行结果:
前面%d,表示输出一个整数(后面会讲),这时会把‘A’的ASCII值输出,%c表示输出一个字符,这时候才是输出A。
char占一个字节,也就是8位,常用于字符型数据储存表示。数值范围 -2^(8-1) ~ 2^ (8-1)-1。
为什么是8-1次幂,而不是8次幂。因为最高适用于表示符号,当最高位是0表示正数,最高位是1时表示负数。为什么正数要减一呢?因为正数是从0开始计数,所以最大为 2^ (8-1)-1,而负数是从-1开始计数。
unsigned char 表示无符号型字符型,数值范围位0~2^8-1
4.2整型数据
用int定义进行定义
例如int data2 = 10;
代码如下:
#include <stdio.h>
int main()
{
int data2 = 10;
printf("%d\n",data2);
return 0;
}
运行结果如下:
常用于存储整数 。在16位单片机当中占2个字节16位(16位计算机现在应该没有了)。在32位以上单片机和计算机中占4个字节32位,数值范围-2^(32-1) ~2^(32-1)-1 。而unsigned in数值范围是在0 ~2^(32)-1 ,至于为什么要减一前面讲过。
4.3浮点型数据
常用的有两种类型单精度float型和双精度double型,什么意思?给大家举个例子:
代码如下:
#include <stdio.h>
int main()
{
float a = 1111.111111111;
double b = 1111.111111111;
printf("%f\n%lf",a,b);
return 0;
}
运行结果如下:
我们发现float型在小数点3位以后已经不是原来我们赋的值,而double还是我们赋的值。float算上前面四位加上小数点后面3位有7位有效数字。而double事实上有16位有效数字。
5.数据运算
5.1算数运算
算数运算符:
+:加法运算符
-:减法运算符
*:乘法运算符
/:出发运算符
%:求余运算符(%两侧均应位整型数据,如7%3的余数为4)
例如:
#include <stdio.h>
int main()
{
int a = 10,b = 3;
int c,d,e,f,g;
c = a + b;
d = a - b;
e = a * b;
f = a / b;
g = a % b;
printf("%d,%d,%d,%d,%d\n",c,d,e,f,g);
return 0;
}
运行结果:
5.2强制转换
我们发现a/b结果是整数而不是小数,是因为int是储存整数,我们要想得到有效结果必须先要定义一个浮点型,还要强制转换。
例如:
#include <stdio.h>
int main()
{
int a = 10,b = 3;
double h;
h = (double )a / b;
printf("%.2lf\n",h);
return 0;
}
运行结果
我们发现此时输出已经有小数部分了。
强制转换,是指两个数据类型不同时,使用在需要转换的数据前加上转换的类型
格式:(数据类型)需要转换的数据
注意:1.字节小的可以向字节大的自动转换,但字节大的不能向字节小的自动转换
2.char可以转换为int,int可以转换为double,char可以转换为double。但是不可以反向。
5.3++ 自增运算符和 --自减运算符
这个两个运算符需要注意放的位置
这两运算符放在前面是先使变量的值自增(或自减),然后再以变换的值参与表达式运行。当这两运算符放在后面是先使变量参与表达式运行,然受使变量的值自增(或自减)。
例如:
#include <stdio.h>
int main()
{
int a = 1,b = 2;
int c = 1,d = 2;
printf("%d,%d\n",++a,++b);
printf("%d,%d\n",c++,d++);
printf("%d,%d\n",c,d);
return 0;
}
我们发现最后的结果,就是因为放的位置不同所以,才导致结果不同。
5.4位运算
位运算在嵌入式当中用的有点多现在向大家介绍一下:
&: “按位与”运算 ,将运算的两数转化为二进制数,两个对应的数同为1时结果位才为1,否则为0。
比如80和23:
80转为二进制为 101 0000
23转为二进制位 1 0111
1 0 1 0 0 0 0
& 0 0 1 0 1 1 1
结果为001 0000转换为十进制数为16注意是右对齐,两位数转为二进制数,位数要相同,位数不足时用0补齐。
同时两个对应的数同为1时结果位才为1,否则为0。
|: “按位或”运算,将运算的两数转化为二进制数,两个对应的数只要有一个数为1时结果位为1,否则为0。比如80和23:
1 0 1 0 0 0 0
| 0 0 1 0 1 1 1
结果为110 0111转换为十进制数为103。同时两个对应的位数一个为1时,结果为1,否侧为0。两个数同为1时需要进1。
^: “异或“运算符 ,将运算的两数转化为二进制数,两个对应的数须不相同结果位才为1,否则为0。比如80和23:
1 0 1 0 0 0 0
^ 0 0 1 0 1 1 1
结果为100 0111转换为十进制数为71。同时两个对应的数须不相同结果位才为1,否则为0。
~: “取反”运算符,将参与运算的数转化为二进制按位求反,即0变1,1变0。
比如80和23
~101 0000 = 010 1111
~1 0111 = 0 1000
80取反为10 1111转换十进制数47,23取反为0 1000转换十进制数为8
<<:"左移"运算符,将运算符左边运算的数转化为二进制数左移若干位,右边的低位用0补齐。
例如23
23 << 2 => 0001 0111<< 2 =0101 1100
将0001 0100 0000转换为十进制数为92
>>:"右移"运算符,将运算符左边运算的数转化为二进制数右
移若干位,左边的高位用0补齐。(该数是正数)
例如80
80 >> 2 => 0101 0000 >> 2 = 0001 0100
将0001 0100转换为10进制数位20。
所有位运算只能对整型数据操作,
5.5复合运算符
+= :例如 a += b 等价于 a = a + b
-= :例如 a -= b 等价于 a = a - b
*= :例如 a *= b 等价于 a = a * b
/= :例如 a /= b 等价于 a = a / b
%=:例如 a %= b 等价于 a = a % b
类似的还有<<=,>>=, ^=,&=,|=复合运算符。
6.格式输入输出
6.1格式输出
printf函数的作用是向计算机系统默认的输出设备输出一个个多个任意类型的数据。
printf函数的一般格式为:
printf(“格式控制”,输出列表);
“格式控制”由双引号括起来的的字符串,主要包括格式说明和需要原样输出的字符。
1.格式说明:
由“%”由格式字符组成,如%d(整数), %f(小数)等(也称为占位符),作用是将要输出的数据转换为指定的格式后输出。C语言中输出函数中的格式字符见下图:
![在这里插入图片描述](https://img-blog.csdnimg.cn/b260a95cf83146bfa37971a0190290b2.png)
#include <stdio.h>
int main()
{
int a = 80;
float c = 80.1111;
char d = 'a';
printf("%d,%.2f,%c\n",a,c,d);
return 0;
}
输出结果为:
可以看到输出整数时占位符为%d,小数为%f,字符为%c
这里强调一下%f,当我们需要2两位小数时,只需要%.2f就可以了。我们需要几位小数,在%后面加个小数点写上你需要的小数位数就行了。(不要忘记格式字符)
2.普通字符:
需要原样输出的字符,也就是双引号里面除了格式字符,转义字符剩下的就是普通字符。如“printf(“sum = %d\n”)”里面除了%d,\n剩下的“sum =” 就是普通字符。
6.2格式输入
这个函数对于初学者来说是个大坑。
第一坑:取地址符号&
scanf函数的一般格式为:
scanf(“格式控制”,地址表列);
“格式控制”的含义和printf函数里面一样。“地址表列”是由若干个地址组成的列表,可以是变量的地址,或字符串的地址。(数据输入完成敲击回车键)
什么时变量的地址?也就是&+变量名,为什么&变量名会是变量的地址?指针那章会讲,同样的字符串的地址后面也会讲。
例如:
#include <stdio.h>
int main()
{
int a ;
printf("请输入一个数\n");
scanf("%d",&a);
printf("这个数是:");
printf("%d\n",a);
return 0;
}
运行结果
一定要注意一定要加上取地址符‘&’,不然程序运行结果会和预期不一样
上面那段代码去掉取地址符‘&’会出现下面这种情况
我输入了一个数据但是最终没有输出,一定要注意。
第二坑:”原样输入“
格式控制中若出现普通字符,输入数据时必须原样输入
例如:
#include <stdio.h>
int main()
{
int a,b,c;
printf("请输入三个数\n");
scanf("a=%d,b=%d,c=%d",&a,&b,&c);
printf("这三个数分别是:\n");
printf("a=%d,b=%d,c=%d\n",a,b,c);
return 0;
}
运行结果
大家发现没,输入时scanf里面的格式控制里除了占位还有其他普通字符,在程序运行时输入数据时也要把这些普通字符输入进去。否则的话,看下面:
看见没输出的结果和我们输入的不一样(”所谓因果关系“)
所以我推荐大家这样写,格式控制里什么都不要加,切换下一个数时,只需要敲击空格和回车就行
如下:
#include <stdio.h>
int main()
{
int a,b,c;
printf("请输入三个数\n");
scanf("%d%d%d",&a,&b,&c);
printf("这三个数分别是:\n");
printf("a=%d,b=%d,c=%d\n",a,b,c);
return 0;
}
敲击空给切换下一个整数数据输入,输入完成敲击回车如下所示
或者利用回车切换下一个整数输入,输入完成敲击回车
<font color = red>这是第二坑,一定要注意格式控制里面有没有其它普通字符。
第三坑:字符输入
话不多说直接看例子
#include <stdio.h>
int main()
{
char a,b,c;
printf("请输入三个字符\n");
scanf("%c%c%c",&a,&b,&c);
printf("这三个字符分别是:\n");
printf("第一个字符:%c,第二个字符:%c,第三个字符:%c\n",a,b,c);
return 0;
}
噫!为什么会这样呢?输入的字符是a,b,c。最后输出只有第一个字符输出正确剩下两个输入空格,第二个字符输出是空格,第三个输出的字符是我输入的第二个字符。试一下其它输入切换。
第一个字符输出和第三个字符输出字符跟上面的情况一样,而第二个字符输出是一个换行了(回车)并且我好像没有输入三个字符。(回车)
试一下其它方法
这次成功了
注意字符输入时切换下一个时,不要空格和回车。因为空格和回车也属于转义字符。直接输入字符就行,会自动切换下一个,输入完成敲击回车就行。
第三坑:混合输入
我利用scanf输入不同类型的数据时会发生什么样的变化了?马上告诉你。
#include <stdio.h>
int main()
{
int a;
char b;
float c;
printf("请输入数据\n");
scanf("%d%c%f",&a,&b,&c);
printf("这三个数据分别是:\n");
printf("第一个:%d,第二个:%c,第三个:%f\n",a,b,c);
return 0;
}
运行结果
输入整型数据,输入完成,没有空格回车直接输入字符数据,紧随其后输入浮点数据。输出结果跟输入顺序一样。但是中间我输入时敲击空格和回车会怎么样?
敲击空格:
敲击回车:
我们发现这两种情况,跟字符输入时情况一样,解决方法也是跟字符输入一样。
注意:混合输入时要注意数据类型。比如整数型输入完,下一个字符型就直接输入。如果是整型和浮点型需要空格和回车切换下一个数据输入否侧会导致数据错位。比如整数型输入完成,直接输入浮点型数据,系统会将小数点后面的数据判定为浮点数据。(不推荐这样输入)
例如:
将上面代码修改一下:
#include <stdio.h>
int main()
{
int a;
char b;
float c;
printf("请输入数据\n");
scanf("%d%f%c",&a,&c,&b);
printf("这三个数据分别是:\n");
printf("第一个:%d,第二个:%f,第三个%c\n",a,c,b);
return 0;
}
运行结果:
6.3其它输入输出
getchar 输入一个字符
putchar 输出一个字符
puts 字符串输出
gets 字符串输入(这个字符串会详细的讲)
我们先来看一下例子
#include <stdio.h>
int main()
{
char c;
puts("请输入一个字符");
c = getchar();
puts("你输入的字符是:");
putchar(c);
return 0;
}
输出结果
puts和printf的区别:
1.puts输出可以自动换行,而printf不行
2.puts只能输出字符串,而printf可以支持多种输出。