三天学会C语言编程|下篇

跟风的eassy 2019-02-01

前面两篇文章(《三天学会C语言编程|上篇》和《三天学会C语言编程|中篇》)对C语言进行了基本的介绍,通过这两篇文章基本上就可以编写简单的C语言程序。本篇作为最后一篇,将介绍C语言中最为复杂的部分,也就是控制语句、指针和复合数据类型等内容。

控制语句

通过上面的知识只能写从上往下依次执行的程序。显然这个不能满足实际开发的需求,比如有的时候我们要根据不同的情况执行不同的代码,或者需要重复执行相同的代码等场景。C语言中有多中控制语句,实现对程序不同流程的控制,下面我们以例子的形式进行介绍。

#include <stdio.h>
/*这个函数实现成绩的转换,如果大于等于90分则打印“优秀”, 如果在80到90之间,则打印“良好”,如果在70-80之间则打印“中等”, 如果在60到70之间则打印“及格”,否则打印“不及格”。*/
int print_score(unsigned int score)
{
 /* if 是C语言的判断语句,用于判断是否执行后面的代码。
 * 在if关键字后是具体的判断条件表达式,表达式需要
 * 用括弧包括。*/
 if ( score > 100 ) 
 { /* 如果条件判断后执行的代码是多行,则需要有{作为执行体的头。 */
 return -1; /*由于成绩不会大于100,因此这里返回-1,表示错误*/
 } /* 如果条件判断后执行的代码是多行,则需要有}作为执行体的尾。
 * 如果只有一行代码则不需要{和}两个字符*/
 /* 下面进行分类打印 */
 if ( score >= 90 ) { /* 语句块标识符{不一定要另起一行,可以与if在同一行。*/
 printf("优秀
");
 }
 else if ( score >= 80 ) { /* 语句 else if 表示另外一种情况。 如果上面符合条件,则不会执行本行。*/
 printf("良好
"); 
 }
 else if ( score >= 70 ) {
 printf("中等
");
 }
 else if ( socore >= 60 ) {
 printf("中等
");
 }
 else { /* else后面可以没有if语句,这样该语句不进行任何判断。如果前面都不满足条件,则到最后执行该语句。*/
 printf("不及格
");
 }
 
 return 0; //返回0表示执行成功
 }
/*上面实现了程序的分支控制,也就是不同的条件执行不同的代码。还有一种情况是需要不断执行某一项重复的计算。这时就需要用到循环语句。
下面这个函数执行连续整数的累加和,也就是从begin按1递增,一直到end的累加和。比如从5开始一直到9,也就是5 + 6 + 7 + 8 + 9。下面看看如何用循环语句实现这个功能。*/
int sum(int begin, int end)
{
 int index = 0;
 int result = 0;
 /* 循环的关键字是for, 后面()里面的是控制语句。括弧是必须的。括弧内用分号“;”将控制语句分为3部分。第一部分进行初始化,只执行一次;第二部分进行条件判断,每次执行,如果符合条件则执行循环体({}内,这个在单行的情况下可以省略)内的内容,否则跳出循环;最后一个则执行一些额外的运算。上面三部分任何一个都可以为空,三者也可同时为空,但分号不能省略。 */
 for (index = begin; index <= end; index++) 
 { /* 这个是开始字符,同判断语句,这里不做过多解释*/
 result = result + index;
 }
 return result;
}
/* C语言中还有另外一个关键字实现循环控制,那就是while语句。*/
int sum2(int begin, int end)
{
 int index = 0;
 int result = 0;
 /*想必大家已经找到规律了,while循环也是关键字后面是括弧,然后是循环体。 while语句在括弧中只有一个条件判断,如果满足条件则执行循环体,如果不满足则从循环退出。*/
 index = begin;
 while(index <= end)
 {
 result = result + begin;
 index ++; 
 }
}
int main(void)
{
 int score = 80;
 
 print_score( score );
 sum(1, 5);
 sum2(1, 5); 
}

本文作为入门级教程并没有介绍全部的循环语句,但作为入门已经够用了。后续再详细介绍更多的用法。

指针

指针给了我们更大的权限,可以让我们直接操作系统的内存。但是指针也是C语言中最为复杂的部分,也是饱受诟病的部分。只是由于指针的存在使得C语言开发的软件出现问题的复杂度更大,也更难解决。凡事有利有弊,废话少说,我们看看什么是指针。

简单的理解,指针其实就是内存的地址。由于我们要访问内存,内存肯定要有个编号,这样我们才知道访问哪里的内存。有人可能会说,你不是在前面说通过变量名称进行访问吗?是的,但是变量名称只是在我们编程层面使用内存的方式,真正到操作系统层面都是通过内存的地址进行访问的。

了解了指针的概念之后,那我们现在谈一下什么是指针变量。我们知道变量是存储数据的,从名称上可以推测出来指针变量就是存储指针的。没错,指针变量就是存储指针的变量,也就是存储内存地址的变量。

三天学会C语言编程|下篇

图1 变量与指针变量示意图

为了便于说明什么是指针及指针变量,我们通过图1进行。假设我们有一个整形变量age,其中的值是0x12345,数据存储在0x1000(这里是为了便于说明,实际位置值的格式大概类似这样,0x7ffc6a95fb14)的位置。

现在我们想用另外一个变量(比如名称为age_tmp)将该变量的地址保存起来,而且可以通过age_tmp访问age变量中的内容,那该怎么办?没错,就是定义一个指针变量。如图1所示,age_tmp就是这个指针变量,它在0x0800的位置,其内部存储的值是age的地址。好了,废了半天话,那具体怎么编写代码呢?下面我们通过一个例子说明。

#include <stdio.h>
int main(void)
{
 int age = 0x12345;
 int *age_tmp; /* 这里是定义一个指针类型的变量,仔细看一下在变量名称前有个星号(*),这个代表变量是指针变量。这里定义的是整形指针变量,我们可以定义任何类型的指针变量。通常,某种类型的指针变量只能存储该类型变量的指针(地址)。 */
 age_tmp = &age; /*这里是将变量age的地址赋值给指针变量age_tmp,注意看age前面有个与符号(&),这个是取变量地址的意思。*/
 printf("age value: 0x%x
", age); /*打印变量的值*/
 printf("age address: %p
", &age); /*打印变量age的地址*/
 printf("age_tmp value: %p
", age_tmp); /* 打印指针变量的值*/
 printf("age_tmp address: %p
", &age_tmp); /* 打印指针变量的地址*/
}

如下是程序执行后的结果,可以看出值的关系与图1是完全一致的。

age value: 0x12345
age address: 0x7ffd64adf68c
age_tmp value: 0x7ffd64adf68c
age_tmp address: 0x7ffd64adf690

好了,关于指针的相关内容就先介绍到这里,关于指针足够专门写一本书了。

复合数据类型

结构体

C语言最为厉害的地方在于可以支持复合数据类型,所谓复合数据类型就是可以将集中数据类型进行组合封装,形成另外一个新的数据类型。实现这种强大功能的名称叫做结构体,结构体通过struct关键字实现,并用{}界定结构体的内容。下面我们看一个具体的例子。

#include <stdio.h>
/*下面是结构体的定义,需要关键字struct,后果是结构体的名字。*/
struct new_type
{ /*结构体具体内容有左大括弧开始。*/
 int number; /*成员变量的第一根我们平时定义变量一样 */
 long age;
 float score;
}; /*结构体的具体内容以右大括弧结束,注意后面还有一个分号。*/
int main(void)
{
 struct new_type var_name; /* 如何使用新的变量类型,定义方式与普通变量一样,只是需要有struct关键字。 */
 var_name.number = 12; /* 对新类型变量成员赋值的方法,中间用点符号(.)连接变量名称和成员名称。 */
 var_name.age = 15; 
 var_name.score = 96.5;
 printf("score: %f
", var_name.score);
}

结构体同样也可以有指针类型,本文暂时不做介绍。这部分内容我们后续专门介绍。

数组

从名称上也可以看出来,数组是指一组数数组是用来存储一系列数据,而且是一系列相同类型的数据。

三天学会C语言编程|下篇

图2 数组变量示意图

如图2所示,我们假设一个整型的数组变量,名称为new_array,由图可以看出其数据在内存总会依次存放。这样有个有点,我们知道该变量的首地址,就能知道后续其它成员的地址,因此也就可以直接访问。下面我们通过实例解释一下。

#include <stdio.h>
int main(void)
{
 int new_array[4]; /* 数组的定义通过在变量名称后面根一对中括号确定,中括号里面的整数是该数组的大小,也即存储几个成员。*/

 printf("first member: %d
", new_array[0]); 
 /* 数组的访问也是通过在变量名称后面跟一个中括弧,其里面的整数表示要访问哪一个成员,需要注意的是数组的成员是从0开始的,表示第一个成员。另外,这里没有对成员进行初始化就进行访问,因此内容是随机的。 */
 new_array[0] = 1; /*成员初始化的方法*/
 new_array[1] = 2;
 printf("first member: %d
", new_array[0]); /* 初始化后再次访问 */
}

下面是运行后的结果:

first member: 4195840
first member: 2

数组可以是任何类型的上面只是数组的基本用法。数组可以一开始就初始化,也可以结合指针使用。

总结

到今天本文就算结束了,学完这些基础知识只能算刚抬起脚迈进门槛,另外一只脚还在外面呢。后面需要学习的内容还多着呢。

三天学会C语言编程|下篇

三天学会C语言编程|下篇

本文最后给大家推荐2本入门的教程《C语言入门经典》和,首先声明并非广告,本文提供电子版下载,电子版下载地址请执行如下两步获取:

1) 转发本文

2) 私信本号,发送 1213

第一本书是编程语言先驱者Ivor Horton的经典之作,是C语言方面最畅销的图书品种之一。本书集综合性、实用性为一体,是学习C语言的优秀入门教材,在世界范围内广受欢迎,口碑极佳。而且译者也是计算机领域的专家,值得作为入门级的教程。

第二本书可以作为进阶阅读,里面有很多C语言的高级特性。

相关推荐