1-2 一文搞定C51单片机的C语言(长文警告)

Hello大家好呀,这里是小X。
相信大家已经安装好了需要的软件了吧。今天小X想要和大家分享的,是单片机的C语言。
如果大家的C语言功底比较扎实,可以跳过这篇文章。但如果比较菜,那可以多看几遍。日后需要用到的函数,小X也会整理在文章里面,方便大家查阅。
对于C语言,相信大家并不陌生。但是对于单片机所使用的C语言,相信就不是那么熟悉了。所以,这篇文章,小X就带大家详细的缕一缕单片机上的实用C语言。

1.1 C语言初步

聊到这里,有的小伙伴就要问了,说小X,你不是说过咱们这单片机的学习是不要太多C语言的吗?
话是这么说的没错啦。但是啊,C语言毕竟是51单片机的基础,毕竟连名字都叫80C51,哈,开玩笑的,C指的是商用的意思。但是,C语言的确是这款单片机绕不开的基础。
有关C语言的介绍部分,在开发攻略上花了很大的篇幅来讲。大家可以在看它的同时看一下小X 的内容。开发攻略上的很多东西都是大家不需要掌握的,小X已经帮大家把它们忽略掉了。

1.1 函数(function)

说到函数,相信小伙伴们可能会一头雾水。为什么C语言里还会有函数这个东西?
实际上,将它称为“函数”是不尽准确的。应该是翻译的问题。
C语言是一款类似于“拼图”的语言。它会按照一定的顺序依次执行用户所写的指令。就像在高中我们学过,函数是自变量和因变量之间的对应关系,而在C语言中,所谓的函数却是指程序每一步应该做什么的拼图,所以,将函数称之为“块”或“步”会更加合适。

1.1.1 函数的构成

说起数学中的函数,相信大家并不陌生。一个函数的基本组成,有三个:
1.自变量(x)。
2.因变量(y)。
3.对应关系f(x)。
对于C语言,也是这样,一个函数也有几个重要的组成部分。例如:

int function()
{
	printf("a\n");
}

以上,就是一个很简单的函数。这个函数大体可以分为以下五部分:

int 
xxx (function)
()
{}

这是一个函数的核心部分。其中:
int:定义了函数的类型,相似的还有void、char等。但是,在C51单片机中,咱们只要考虑int类型的函数就可以了。只要是在C51单片机里写函数,就先写个int。

xxx:这是函数的名字。既然提到了名字,就可以起自己喜欢的名字了。例如,你可以这么写:

int woxihuancaixvkun()
{
	printf("Hello world!\n");
	return 0 ;
}

别看了,就是拼音的”我喜欢蔡徐坤“。
在C语言中,函数的名字十分自由。换句话说,只要编译的时候没报错,你爱叫什么都可以。至于编译是什么,之后再讲。至于什么时候会报错呢?基本就是在以下的几方面:

1.函数重名。比如,小X认为一个函数很重要,直接就叫他main函数。的确很重要,但这个main函数以及有了也就是说,小X写的函数和另一个函数重名了。这样就不可以了。

2.使用了保留字。例如,小X认为一个函数里使用了多个int,就直接叫这个函数为int函数。可int本身就是一个函数,这样,机器就不知道小X究竟要干什么,也就不能执行了。

3.使用了除英语外的语言。C语言目前只能用英语编程,连中文标点都不能出现。如果小X不用拼音来写这个函数名,而直接叫他”我喜欢蔡徐坤“,毫无疑问是会报错的。
顺道一提,易语言就可以用中文编程,但很少有人用了。

():传参。很多时候里面是不需要加东西的。它的目的是告诉计算机,这个新函数从别的函数那里拿了什么东西,如果没有,就空着即可。就算是空着也不能省略。例如:

int main()
{int a }

int function(int a)
{b}

别试了,什么都不会出来。
这个例子是指,function这个函数从main里面”继承“了a这个自变量。这样,大家就可以在function里面使用它了。

最后,小X写了一个花括号{ }用以存储函数究竟要干什么。例如,要输出字符,就在里面添加输出字符的命令。要计算加减法,就添加计算加减法的命令。一个函数执行的范围,就是花括号里所包含的所有语句。
注意,函数后面不加花括号也不是不可以。
如果不想在函数的后面添加花括号,那就只有一种情况:这个函数只有一条语句。也就是说,这个函数在一个分号内就能结束,而不是一行内。就如同接下来要说到的分号。

就小X个人而言,习惯于在每一个函数的下一行开始用花括号,无论这个函数是不是一个单行的函数。大家也可以试试这样的书写,十分的简洁明了。

分号;小X将其拿出来单独拿出来聊,是因为这个点经常会出错。
C语言是机器在执行,不会有人类的情绪。
例如,这个程序:

#include <stdio.h>
int main()
{
	printf("Hello world!\n");
	return 0 ;
}

看着很好看,但我写成:

#include <stdio.h>int main()printf("Hello world!\n");return 0 ;

这样可不可以呢?
答案是可以的。C语言对于语句的判断标准只有一个,就是找分号。一个分号就是一条语句。回车只是让咱们看起来比较舒服的格式工具而已,在运行的时候是会忽略掉的。
就像上面提到的,一个函数里不止有一条语句,所以,为了让它能好好的执行多条语句,需要把所有的语句都放在花括号里。每一条语句结束的时候都要打分号,否则它会认为还没有结束。这个很重要。

1.1.2 函数的使用

函数的使用很简单。就像小X说的,C语言是一款用代码拼起来的拼图。
例如,小X想要实现一个程序,计算输入的两个数字的和。那该怎么写呢?

分析题设:需要一个函数,那如上面讲过的,可以先写:

int function()
{

}

由于不用传参,所以括号里面就可以空着。
再看一个函数要干什么。由于它提到了a和b两个数字,以及求和,那就分别写上:

int a,b,sum;
sum = a+b;

那这里的int是什么意思呢?
这里的int和函数前面的int类似,也是告诉计算机,后面的字符是什么类型的。没有如果一个函数中的字符是第一次出现却没有被定义,程序将不知道它是什么。如同英语单词要被收入词典才能有意义,int就是一个收入词典的过程。

有了这两个,那咱们的函数就可以写作:

int function()
{
	int a,b,sum;
	sum = a+b;
}

ok了。其中,sum就是a和b的和。只要日后的函数调用function函数,就能快速的算出a和b的和了。
现在听不太懂也没关系,只要从下一章开始认真的跟着小X慢慢来就可以了。单片机编程需要用到大量的函数,小X会慢慢给大家讲每个语句的作用的。

1.2 单片机开发的常用函数

下面,为大家介绍几个常用的函数,这些函数会伴随大家开发这款单片机的日日夜夜。

1.2.1 main(主函数)

main函数是C语言都无法绕过的一个点。无论是C语言最经典的程序:

#include <stdio.h>
int main()
{
	printf("Hello world!\n");
	return 0 ;
}

还是C++的经典程序:

#include<iostream.h>
using namspace std;
int main()
{
	cout << Hello world << endl ;
	return 0 ;
}

都绕不开这个main。但这个main到底是个啥子玩楞呢?
简单的说,main是一个程序的切入点。
拿到一个程序,其实它有无数行。小X就曾经写过上千行的长代码。想要程序自己判断从哪里开始执行是不现实的,况且,有的程序员喜欢先写好一些模块,最后再将他们组合在一起.也就是说,排在前面的语句不一定先执行。例如:

int woxihuancaixvkun()
{
	a ;
}
int main()
{
	b ;
}

那么,先运行的是a还是b呢?
显然,是b。在特定的时候,这么写可以极大的美化一个函数。
你是爽了,可计算机炸了。计算机怎么知道先运行哪个?
在这种情况下,main函数就应运而生了。计算机在执行一个函数的时候,首先找的是main函数,从main函数里面开始反复行刑,额不是,依次执行。这样,执行代码的顺序就可以被确定了。

1.2.2 if (条件函数)

一个程序不可能只有加加减减,还得包括逻辑运算。
例如,“如果大家有C语言的基础,就跳过这篇文章”。这是一个函数能做到的,但咱们能用加加减减做到呢?
这时候,咱们需要逻辑运算
这里小X犯下C语言的大忌——中文编程,来让大家理解if函数。
说到函数,那少不了这个:

int main()
{
	
}

有同学可能要问了,说为什么不是if是main呢?
这里就要说到,if这个函数已经被定义了,不需要大家自己去定义。这样的函数有很多,包括咱们自己定义的函数,只要已经被定义了,就可以在其他函数里面直接拿来用了。所以,对于if函数是怎么int出来的,咱们不用去管,直接用就行了。
除了main函数,因为main函数可以有不同的定义方法。
扯远了。那接下来要干什么呢?
当然是条件。
对于逻辑函数来说,条件就是参。既然要传参,那条件自然要写在()里。
那就很明了了,条件这么写:

if(读者有C语言编程基础)

对,if函数的条件语句写在括号里即可。那条件有了,执行什么呢?
执行“跳过这篇文章”。
那总体来说,就是这么写的:

int main()
{
	if(读者有C语言编程基础)
	{
	跳过这篇文章;
	}
}

好了,一个简单的条件分支函数已经写完了。当然,这个函数是运行不了的,得用英文写才行。
if就是一个“如果……就……”的语句。那如果要实现否则该怎么写呢:
“如果大家会C语言,就跳过这篇文章,如果大家不会,就多读几遍。如果大家即会又不会,来抽小X的大嘴巴子”
可见,这里面出现了三个分支,单分支的if就有些不够用了。

1.2.3 eles if 和 else

为了解决分支不够用的问题,人们发明了else这个函数。
它和if函数十分相似,可以这么理解:

if(a)
{a}
else if (b)
{b}
else if (c)
(c)
else
{d}

当然想要多少种情况,就嵌套多少层。
它可以这样想:只要符合事件a,就执行a语句。如果不符合事件a,就继续往下运行,到了判断事件b。如果符合事件b,则执行语句b。C条也是同理。当以上都不符合,那就执行else(其他的情况),就是事件d。
eles没有参数可传,后面就不打括号了。这个比较特殊,切记。
那我提出的那个问题,就简单了:

int main()
{
	if(读者有C语言编程基础)
	{
	跳过这篇文章;
	}
	else if(读者没有C语言基础)
	{
	多读几遍这篇文章;
	}
	eles
	{
	来抽小X的嘴巴子;
	}
}

讲到这里,条件语句已经结束了,是不是很简单呢?

1.2.3 while(当循环)

假设给出一个题设:“小X写一篇文章赚一分钱,多少文章能赚到一个亿”
嗯,很哲学的问题。很明显是加减乘除的问题,但小X要是只让大家用加减呢?
这时,只要用一个当循环就行了。
直接上例程:

#include <stdio.h>

int main() {
    int  初始赚钱数量
    int  初始文章数量
    while (小X赚到的钱 < 100000000)
     { 
        初始赚钱数量 + 0.01; // 每写一篇文章赚一分钱
        初始文章数量 + 1; // 文章数量加一
    }
}

前面两个int已经讲过了,是让计算机理解两个变量。
直接看循环体。
当咱们看到while的时候,把它替换为“当”字。那这句话就是:
“当小X赚到的钱小于100000000时,执行以下语句”。
然后,特别的,语句执行完时,会返回while继续,直到小X赚到的钱不满足括号里的等式,才会跳过这个while循环,往下执行。

当while(1)时,这个循环会一直执行,永不停止。

讲到这里,第一种循环语句已经讲完了。
为什么是第一种?在数学种,循环语句有两种,一种是当循环,还有一种是直到型循环

1.2.4 for(直到型循环)

接下来,一起来看看更为复杂的for循环。
for循环的应用会比while更广,但因为它出现的比较靠后,所以大家可以慢些掌握。
for 循环语句的一般形式为:

for (表达式1; 表达式2; 表达式3)
{
        语句;
}

首先要强调两点:

  1. 表达式1、表达式2和表达式3之间是用分号;隔开的,千万不要写成逗号。

  2. for(表达式1;表达式2;表达式3)的后面千万不要加分号,很多新手都会犯这种错误——会情不自禁地在后面加分号。

因为 for 循环只能控制到其后的一条语句,而在C语言中分号也是一个语句——空语句。所以如果在后面加个分号,那么 for 循环就只能控制到这个分号,下面大括号里面的语句就不属于 for 循环了。

下面来看看它的执行过程:

求解表达式1。
求解表达式2。若其值为真,则执行 for 语句中指定的内嵌语句,然后执行第3步;若表达式2值为假,则结束循环,转到第5步。
求解表达式3。
转回上面第2步继续执行。
循环结束,执行 for 语句下面的语句。

从这个执行过程中可以看出,“表达式1”只执行一次,循环是在“表达式2”“表达式3”和“内嵌语句”之间进行的。

for语句最简单的形式是:

for (循环变量赋初值; 循环条件; 循环变量增值)
{
    语句;
}

下面给大家写一个程序,求 1+2+3+4+…+100 的总和。

# include <stdio.h>
int main(void)
{
    int i;
    int sum = 0;  //sum的英文意思是“总和”
    for (i=1; i<=100; i=i+1)  //++是自加的意思, ++i相当于i = i + 1
    {
        sum = sum + i;  /*等价于sum += i;但是不建议这么写, 因为sum = sum + i看起来更清楚、更舒服*/
    }
    printf("sum = %d\n", sum);
    return 0;
}

这个程序是可以真的跑起来的,输出结果是:
sum = 5050

这个程序的功能是实现求 1+2+3+4+…+100 的和,如果不用循环,加一次就要一条语句,加 100 次就要 100 条语句。这里是从 1 加到 100,要是从 1 加到 10000 那就要 10000 条语句。但有了循环就很方便了,你想加到多少就加到多少,只要改一个参数就可以了。所以循环很重要。

下面按照执行过程看看上面这个程序是怎样执行的。

  1. 首先定义一个循环变量 i。定义的时候可以不给它赋初值,在 for 循环里面再给它赋初值也行。程序中可以在定义 i 的时候就给它赋初值,那么 for 循环里的“表达式1”就可以省略了,但分号不可以省略。

这样的话,执行的时候就跳过第1步,直接进入第2步,其他的不变。所以程序也可以像下面这样写:

# include <stdio.h>
int main(void)
{
    int i = 1;
    int sum = 0;
    for (; i<=100; i=i+1)
    {
        sum = sum + i;
    }
    printf("sum = %d\n", sum);
    return 0;
}

当然表达式1加上也行,大不了再重新赋一次值。

  1. 然后定义一个用来存放“和”的变量 sum,并给它赋初值 0,然后进入 for 循环:

首先求解表达式1,即给变量i赋初值,i=1;表达式1只执行这一次,下面都不会再执行了。
然后求解表达式2,若 1<=100 成立,则执行 for 循环中的内嵌语句,即 sum=0+1。
然后执行第3步,变量 i 自加 1,即变量 i 由 1 变为 2。
然后再求解表达式2,2<=100 成立,则执行 for 循环中的内嵌语句,sum=0+1+2。
然后再执行第3步,变量 i 自加 1,即变量 i 由 2 变为 3。
然后再求解表达式2,即 3<=100 成立,则执行 for 循环中的内嵌语句,sum=0+1+2+3。
……

就这样一直循环下去,直到 ++i 等于 100 的时候,求解表达式2,即 100<=100 成立,则执行 for 循环中的内嵌语句,sum=0+1+2+3+…+100。

然后再执行第3步,变量 i 自加 1,即变量 i 由 100 变为 101。然后再求解表达式2,即 101<=100 不成立,则结束循环,执行 for 循环下面的语句即 printf。

以上就是这个程序的执行过程。
下面再给大家写一个程序,求 1 到 100 之间所有奇数的和。

# include <stdio.h>
int main(void)
{
    int i;
    int sum = 0 ;
    for (i=1; i<100; i=i+2) 
    {
        sum = sum + i;
    }
    printf("sum = %d\n", sum);
    return 0;
}

输出结果是:
sum = 2500
for循环大概就讲到这里。日后遇到了,会有更详细的讨论。

1.3 C语言中的符号

C语言里符号很多。这里是几个十分常用的符号:
//:注释。双斜线的后一整行都会被程序忽略,写什么都可以。
/* aaa */:也是注释。会忽略掉aaa部分的所有内容,比双斜杠更好的地方是可以换行。
=:赋值符号。例如:a=b,就是让a的值变得和b一样。
==:判断符号。例如:a==b,就是判断a和b是否相等。
\n:换行符,当计算机读取到这个符号时进行换行操作。单片机里用的很少。
!=:不等号。
<=:小于等于号。
>=:大于等于号。
其他符号几乎用不到,小X就不和大家说了。
今天的分享就到这里,希望下次再和小X见面呀!

  • 20
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值