#include<stdio.h>
int main()
{
printf("Hellow world");
return 0;
}
打印出“Hello world”的这个程序相信每个人都是见过的,这段代码非常的简单,没有调用函数,没有使用指针,没有各种杂七杂八的东西,但我相信,第一次看见这个代码的朋友一定会有很多疑问。
#include<stdio.h>是什么,它凭什么要第一个写,main函数又是什么,printf函数又是怎么打印的,return 为什么要return 0,如果return 1又会怎样,今天我就接着这个简单的程序来说说这些问题。
预处理指令#include
在学习Hello 程序时,大家都会听到一句“使用printf函数打印出Hello world”,既然printf是个函数,那么他的函数原型,定义又在哪里呢
我们框选printf,右键点击转到定义,发现跳转到了stido.h这个头文件页面
也就是说,printf是在stdio.h这个头文件里面定义的,而stdio.h便是我们刚才在#include之后的内容。
这也就说明了,使用#include可以将一写常用的函数或者声明直接拿来使用。
具体的底层是在程序进行预处理时,就会将头文件的内容复制到我们的代码文件中,以便我们进行
函数,变量的调用。编译器看到#include就知道,这是预处理,我要把后面的东西复制进来了。
而对于#include除了可以使用<>,还可以使用“ ”
使用尖括号< >
,编译器会到系统路径下查找头文件;
而使用双引号" "
,编译器首先在当前目录下查找头文件,如果没有找到,再到系统路径下找。
我们通常使用尖括号包含标准库中的头文件,因为标准头文件是在系统路径下的;而对于我
们自己创建的头文件,由于其在当前目录下,因此需要使用双引号。
main函数
再往下面的main函数也值得说说,我们都知道函数可以传递参数,main函数也不例外,只不过在
初期学习的时候我们很少用到主函数的参数,所以我们通常是
int main(void)
实际上main可以传三个参数,
int main(int argc,char *argv[],char * envp[])
argc:表明命令行参数的个数
argv:表明命令行参数数组
envp:表面环境变量
#include<stdio.h>
int main(int argc,char *argv[],char * envp[])
{
printf("参数个数是:%d\n", argc);
printf("参数内容是:");
for (int i = 0; i < argc; i++)
{
printf("%s\n", argv[i]);
}
printf("环境变量是:");
for (int c = 0; envp[c] != NULL; c++)
{
printf("%s\n", envp[c]);
}
return 0;
}
这段代码,我们将打印主函数的参数个数是多少,函数的参数内容是什么,以及环境变量的内容
下面是运行结果:
printf函数
printf函数是我们使用频率非常高的一个函数,但是它也并不像表面那样的简单,
printf()是C语言标准库函数,用于将格式化后的字符串输出到标准输出。标准输出,即标准输出文
件,对应终端的屏幕。printf()申明于头文件stdio.h。
函数定义:
函数原型:
既然是个函数,就会有返回值,printf前面是int,说明会返回一个整形,正确返回输出的字符总
数,错误返回负值,与此同时,输入输出流错误标志将被置值,可由指示器ferror来检查输入输出
流的错误标志。
printf的调用格式:
printf()函数的调用格式为:printf("格式化字符串",输出列表)
格式化字符串包含下面三种情况:
1,字符串常量
2,格式控制字符串
3,转义字符
字符串常量原样输出,在显示中起提示作用。输出表列中给出了各个输出项,要求格式控制字符串和各输出项在数量和类型上应该一一对应。其中格式控制字符串是以%开头的字符串,在%后面跟有各种格式控制符,以说明输出数据的类型、宽度、精度等。
printf的格式控制字符串组成如下:%[flags][width][.prec][length]type
分别为:
%[标志][最小宽度][.精度][类型长度]类型。
除此之外还有一些其他的标志:
printf("%5d\n",1000); //默认右对齐,左边补空格
printf("%-5d\n",1000); //左对齐,右边补空格
printf("%+d %+d\n",1000,-1000); //输出正负号
printf("% d % d\n",1000,-1000); //正号用空格替代,负号输出
printf("%x %#x\n",1000,1000); //输出0x
printf("%.0f %#.0f\n",1000.0,1000.0)//当小数点后不输出值时依然输出小数点
printf("%g %#g\n",1000.0,1000.0); //保留小数点后后的0
printf("%05d\n",1000); //前面补0
其他输出示例不再经行演示
转义字符:
了解了printf三种打印类型后,我们还应该知道缓冲区,在printf的实现中,
在调用write之前先写入IO缓冲区,这是一个用户空间的缓冲。系统调用是软中断,频繁调用,需要频繁陷入内核态,这样的效率不是很高,而printf实际是向用户空间的IO缓冲写,在满足条件的情况下才会调用write系统调用,减少IO次数,提高效率。
printf在glibc中默认为行缓冲,遇到以下几种情况会刷新缓冲区,输出内容:
(1)缓冲区填满;
(2)写入的字符中有换行符\n
或回车符\r
;
(3)调用fflush手动刷新缓冲区;
(4)调用scanf要从输入缓冲区中读取数据时,也会将输出缓冲区内的数据刷新。
可使用setbuf(stdout,NULL)
关闭行缓冲,或者setbuf(stdout,uBuff)
设置新的缓冲区,uBuff为自己指定的缓冲区。也可以使用setvbuf(stdout,NULL,_IOFBF,0);
来改变标准输出为全缓冲。全缓冲与行缓冲的区别在于遇到换行符不刷新缓冲区。
return
1) 求值表达式,终止当前函数,并返回表达式的结果给调用方(该返回值成为函数调用表达式的值)。仅对函数返回类型非 void 的情形合法。
int add(int a,int b)
{
return a+b;
}
2) 终止当前函数。仅对函数返回类型为 void 的情形合法。
void test(int &a)
{
a++;
return ;
}
既然return可以终止当前函数,那我们就比较一下return,break,continue
break:
function myBreak() {
for(var i = 0; i < 5; i++) {
if(i == 3) {
break;
}
console.log(i);
}
}
myBreak();
break: 直接跳出当前的循环,从当前循环外面开始执行,忽略循环体中任何其他语句和循环条件测
试。它只能跳出一层循环,如果你的循环是嵌套循环,那么你需要按照你嵌套的层次,逐步使用
break来跳出。
continue:
function myContinue() {
for(var i = 0; i < 5; i++) {
if(i == 3) {
continue;
}
console.log(i);
}
}
myContinue();
continue: 终止当前的一次循环过程,其 不 跳出循环,而是继续往下判断循环条件执行语句。
只能结束循环中的一次过程,但不能终止循环继续进行。
在编写代码时,应当尽量减少continue的使用,因为很容易会造成死循环。
return
function myReturn() {
for(var i = 0; i < 5; i++) {
if(i == 3) {
return i;
}
console.log(i);
}
}
var s = myReturn();
console.log("s: " + s);
return: 从当前的方法中退出,返回到该调用的方法的语句处,继续执行。
总结
1、return语句的作用
(1) return 从当前的方法中退出,返回到该调用的方法的语句处,继续执行
(2) return 返回一个值给调用该方法的语句,返回值的数据类型必须与方法的声明中的返回值的类型一致,可以使用强制类型转换来是数据类型一致
(3) return 当方法说明中用void声明返回类型为空时,应使用这种格式,不返回任何值。
2、break语句的作用
(1) 只能在循环体内和switch语句体内使用break语句。
(2) 当break出现在循环体中的switch语句体内时,其作用只是跳出该switch语句体。
(3) 当break出现在循环体中,但并不在switch语句体内时,则在执行break后,跳出本层循环体。
(4) 在循环结构中,应用break语句使流程跳出本层循环体,从而提前结束本层循环
3、continue语句作用
(1) continue语句的一般形式为:continue;
(2) 其作用是结束本次循环,即跳过本次循环体中余下尚未执行的语句,接着再一次进行循环的条件判定。
(3) 注意:执行continue语句并没有使整个循环终止。在while和do-while循环中,continue语句使得流程直接跳到循环控制条件的测试部分 ,然后决定循环是否继续进行。
(4) 在for 循环中,遇到continue后,跳过循环体中余下的语句,而去对for语句中的“表达式3”求值,然后进行“表达式2”的条件测试,
最后根据“表达式2”的值来决定for循环是否执行。在循环体内,不论continue是作为何种语句中的语句成分,都将按上述功能执行,这点与break有所不同
标签:语句,return,函数,int,C语言,循环,printf,main From: https://blog.csdn.net/2303_76580416/article/details/139412322