int main()
{
printf("Hello Worldn");
return 0;
}
相信你已经看到了第一个示例代码的效果了。这个程序所实现的效果很简单,就是在屏幕上输出了一行字符"Hello World"。
我们根据这一小段代码,借此了解一些C语言的基础语法知识。
什么是主函数?
首先,主函数main
,一个标准的主函数如下:
int main() // 这是主函数
{
return 0; // 主函数返回值
}
main
翻译成中文是主要的、最重要的意思,而在C语言里面表示一个主函数。(稍后我们会讨论什么是计算机语言里面的函数,以及主函数在C语言程序中的存在意义。)
双斜杠后面的为注释
,打一个比较形象的比喻,注释
就类似于老师在作业本上的批注。
一般来说,注释用于标注这段代码的用途或解释思路等。因为注释不会被当做代码进行编译,所以无论添加什么注释内容,都不会对代码的实际运行产生任何影响。
如上代码中,用注释标出了哪里为主函数
,哪里是函数的返回值
。
什么是函数?
我们先谈谈什么是函数
?在大家的认知里面,函数是数学领域的一个名词,它可能是如下图所示:
但是,这只是数学领域中的函数
,与编程语言中的函数
完全不同。
在编程语言里面,你可以把函数看做一个盒子,这个盒子有如下几个特性:
-
开始执行时,函数可以被输入一些值
-
执行过程中,函数可以做一些事情
-
执行完成后,函数可以返回一些值
让我们看看我们的这个主函数,在这3个特性上,分别做了什么。
-
主函数什么都没有输入
-
主函数打印了一行字到屏幕上
-
主函数返回了0
其中,int
表明了函数的返回值类型
,int
是integer(整数)
的缩写。
main
是函数名
,main
后面的括号()
内为输入参数,目前为空。
return
后跟函数的返回值
,为0。而0是一个整数,和函数名前面的int
对应。
我们总结一下函数的写法公式。
函数返回值类型 函数名(函数输入参数值)
{
做点什么事情
return 函数返回值;
}
写一个自己的函数
我们不如趁热打铁,根据上面的函数写法的公式,写一个两个整数加法的函数。这个函数需要做到:输入两个整数,返回他们相加的结果。
这个既然这个函数是用于计算加法的,我们把函数名取名为add
。当然自定义函数的函数名可以按照自己的喜好来写,就算写成aaaaa也行。不过,为了函数名拥有语义化,方便人阅读理解,我们一般使用英文来作为函数名。
// 这一段代码被称之为add函数的函数定义
int add(int a, int b)
{
return a+b;
}
好的,那我们写完了一个add函数
了。这一段代码被称之为add函数的函数定义。
主函数是C语言程序的入口
上面我们已经自己定义好了一个add函数
,那我们需要怎样来使用它呢?add函数
能直接运行嘛?
答案是不行的。
所有的C语言代码都有一个起始入口,而这个入口就是主函数main
。进入了主函数以后,才能经由主函数来调用其他函数。
这也意味着,每个C语言代码,只能有且只有一个main函数。
我们把代码稍微修改,现在代码如下。
int add(int a, int b)
{
return a + b;
}
int main()
{
int result;
result = add(2, 3);
printf("%d", result);
return 0;
}
当程序运行时,首先会进入主函数main
。接着调用我们刚刚编写的add函数
了。我们传了2个值分别是整数2和3的add函数
。
函数的定义中规定,传2个参数,我们调用的时候,也必须传2个,并且类型也需要一致,否则编译会报错。
那么自然地,我们会想到,主函数是被谁调用的?主函数的返回值必须是int
吗?
主函数在程序开始的时候被自动调用,不需要在程序内主动调用主函数。
而主函数的返回值会返回给调用这个程序的程序。
C语言标准中规定主函数有返回值且必须是int
。如果程序正常结束,一般将返回值设置为0。
调用函数,必须先知道函数
我们再来看看,编译器是怎么理解add
这个标识符的。
编译器会从代码开始,按照从上往下的顺序阅读代码。
编译器首先看到了一个函数的定义,描述了一个叫add
的函数。接着,在main
中需要使用add
,由于编译器已经知道了add
的定义,因此编译器可以正常编译通过。
但是,如果将函数定义和函数调用反过来呢?
首先,编译器看到了add
标识符,编译器会很疑惑,add
是什么呢?编译器无法理解add
究竟是什么。因此,编译器将报错,并停止编译。
什么是变量?
在add函数
计算完毕之后,需要有一个东西来接受add
返回回来的值。所以,我们在add
前面声明了一个int整型
的变量
。
什么是变量呢?你可以把它看做一个空箱子,里面可以装任何其他的和它类型一致的值。
result
只是我们给它起的一个名字,当然,你可以任意起名。比如叫he,叫xiangzi,都可以。
我们把add
返回回来的5,装进了result
。因此,result
里面装着的值是5了。
=
等号,在C语言中是赋值运算符,相信你已经发现它有把右边的值装进左边变量的功能了。和函数一样,这里的等号和数学里面的等号,也是有很大不同的,它并不是相等的意思。
赋值运算符,是能将符号右边的值,装进左边的变量的一种运算符。
下图就是add函数
接受2,3为输入,返回5,被赋值号=
赋值给result
的流程了。
那我们能不能这样写呢?去掉int result;
这一条。
int main()
{
result = add(2, 3);
printf("%d", result);
return 0;
}
答案是不行的,变量必须先声明后使用。
编译器看到result
标识符,但是从未见过result
的定义时,肯定也会疑惑它究竟是个什么类型的变量,甚至它有可能不是变量而是一个函数。这样,编译器只能遗憾地给出一个编译错误的提示,并结束编译了。
int result;
你必须像上面这样,声明有一个变量,名字叫result
,类型是int
。接下来,编辑器就能记下result
标识符为一个int
类型的变量。在后面的代码中,即可愉快地使用这个result
变量了。
什么是字面常量?
那么,像2,3,这种数值,需不需要声明呢?
不需要,他们是常量
,无法被更改。并且一旦被写出来,就已经知道它们是整型的常量了。
同样的,字符串字面常量
也不需要被声明,例如:"Hello Worldn"。被双引号包裹的,我们认为它是一个字符串,以区别于数值。
变量我们可以通过赋值来更改,常量不能更改,所以你不能对它进行赋值。
2 = 3; // 错误
"Hello" = "World"; // 错误
printf函数
int main()
{
printf("Hello Worldn");
return 0;
}
现在,你应该明白了这段代码的大部分含义了。我们再进一步,把它全部解析完。
和add
一样,printf
也是一个函数,但是这个并不是一个自定义函数,而是一个系统自带的函数。
我们把字符串字面常量"Hello Worldn"
传给了printf函数
。运行代码时,我们在屏幕上看到了这行字符。显然,printf函数
的作用就是将字符串输出到控制台上了。
printf
由单词print(打印)
和单词format(格式)
的首字母f组成,意为格式化打印。
int main()
{
int result;
result = add(2, 3);
printf("%d", result);
return 0;
}
让我们再次比较两段代码,我们写Hello World
时只传了1个参数给printf
,但为什么在add函数
后却能传2个给它呢?函数定义的参数个数和类型需要和函数调用时候的保持一致吗?
printf
是一个很特别的函数,它是一个变参函数
,所以可以接受可变数量和类型的输入参数。这里我们无需太过关心怎样写一个可变参数函数,暂时只需要使用它即可。
通过如下示例,我们可以简单了解printf函数
的更多用法。
用于打印一个整数:printf("%d", 整型);
printf("%d", 12345);
用于打印两个整数:printf("%dn%dn", 整型1, 整型2);
// n表示换行,就是从下一行开始再继续打印
printf("A=%dnB=%dn", 123, 456);
我们来总结一下printf
的公式:
printf("XXX占位1 XXX 占位2 XXX占位3", 替换1, 替换2, 替换3);
printf
的第一个参数必须是字符串(被双引号包括)
。其中,占位用%类型
表示。例如:整型的占位符为%d
。后面的替换参数,会依次替换前面的占位。printf
是一个变长参数函数,只要第一个字符串参数占位符写对了,后面可以加任意多的替换参数。
#include命令
printf函数
并不是我们定义的函数,而是系统自带的函数。这个函数被写在文件stdio.h
中,我们要使用printf
就必须先让编译器理解printf
。
我们假定printf
的函数定义写在文件stdio.h
中,用#include
命令,可以将文件stdio.h
的代码复制到我们的代码中。
TIPS:
stdio.h里面并未定义printf函数,但是它里面有printf函数的函数声明。但是,在当前阶段里面,你可以理解为stdio.h里面,写了printf的函数定义。
城职电协
编辑:谢家霞
初审:杨妙芸
复审:薛浩彬
终审:邱小群
发表评论