写在前面
促使我写这篇文章是因为我这几天找了几个一样是大三的同学,与我相同专业相同方向(物联网)的人,除了@小胡同的诗,基本没有什么其他人会现在看起来很简单的编程题目了。问了一下其他同学,他们大部分都说自己C语言是混过的,因为之前老师教的时候说不会指针||结构体||函数 不会写也没有关系,然后他们居然还能过省二级(C语言)???结果到了大三,没人给他们做大腿了,所以基本上课堂上就进入了“休眠模式”,后面的东西基本都听不懂了……所以来这里给大一大二还在学习C语言的同学一点小小的建议。这样才能编的下去代码。
Main函数
总所周知,所有C语言程序基本上都有个Main函数,哪怕是操作系统的代码也逃不过这个Main函数,如果没有Main函数最直接的后果是编译器不知道刚开始的代码在哪里,于是规定使用main函数作为整个程序的入口,一般来说,在完成初始化操作之后放入运行程序栈底位置,有Main函数内部的调用来决定以何种顺序来使用汇编好的各种函数位置。
在《C语言程序设计》厦门大学版(也就是福建省版)
中一个典型的Main函数长成这样子
1 int main() //Main函数返回一个整形变量来表明自己运行情况,默认无参数 2 { 3 //函数体 随便写点什么... 4 return 0; //需要返回值,以便给操作系统留下遗言 5 }
我们看出在这个函数里面,参数部分没有任何参数,因为一般的程序不需要使用什么参数直接就能运行了,一个典型的Hello world里面直接就写printf("Hello world\n");就完事了,也没有什么特别的变换。
为什么要有返回值,如果这段代码不是计算机运行的第一个程序(也就是操作系统),那么就需要一个返回值,让操作系统知道这个程序到底运行的怎么样?是好还是坏,由于某种原因,我们这里采用0作为没有错的返回值。
最可能原因的是0相当于false,操作系统问程序:嘿,程序,你运行的怎么样? 程序:没问题(0,false),操作系统就知道程序没有运行错就不用去管他了,如果程序运行的好好,突然由于一些意外的事情导致没有退出,操作系统就能知道程序到底出了什么错。
但是main函数往往不是这个样子,你可能还讲过下面的Main函数形式
谭浩强/MSDN/C51 典型的main函数
void main() //不需要返回值,所以类型为void 空 { //函数体 }
说起来谭浩强也可能被上古的MSDN的示例坑了,才在自己的C语言书里面写void main()的,MSDN里面的示例真的充满了Void Main
// CalculatorTutorial.cpp : This file contains the 'main' function. Program execution begins and ends there. // #include "pch.h" #include <iostream> void main() //现在是int main() { std::cout << "Hello World!\n"; } // Run program: Ctrl + F5 or Debug > Start Without Debugging menu // Debug program: F5 or Debug > Start Debugging menu // Tips for Getting Started: // 1. Use the Solution Explorer window to add/manage files // 2. Use the Team Explorer window to connect to source control // 3. Use the Output window to see build output and other messages // 4. Use the Error List window to view errors // 5. Go to Project > Add New Item to create new code files, or Project > Add Existing Item to add existing code files to the project // 6. In the future, to open this project again, go to File > Open > Project and select the .sln file
当然排除错误写法之后,void main还常见于C51的程序,C51是应用在8051系列单片机上的一种C语言的变种,主要的编译器为Keil,由于C51编写的程序是直接在裸机(无操作系统)上跑的程序,所以不需要返回值(因为也没有地方可以理你的返回值),但这个只是来自有着40年历史老单片机的倔强而已,现在的单片机使用的C语言跑的编译器一般还是要求使用 int main带返回值的形式(GCC编译器会隐式转换void main为int main带返回值的形式),当然现代的编译器还是会帮你补上返回值的
还有一种学校里面不会教的就是带有参数的main函数,这种main函数常见于Linux 编程(因为一般Linux操作系统不运行图形界面,所以如果不带参数一般无法运行)、
Liunx终端/Windows 控制台 编程中的main函数
int main(int argc,char **argv) { //函数体 return 0; }
argc指示的是传入的参数个数,argv为传入的指令,在Linux中传入的参数0位置一般为自己的名字例如“ls”,剩下就是可选参数位
一般刚学的同学完全没有接触过控制台编程,所以一旦遇到这种东西就会手足无措。
在Windows中你们经常使用的一个带有参数的程序,也许就是ping命令(ping 主机名,向远程主机发送ICMP报文,指示与远程主机是否能进行通信,在这种情况下“主机名”就是一个参数)
而在linux中经常使用带有参数的程序就是cat程序(查看文件内容 c)的程序,因此参数此时作为必须要有的东西
在C语言中由于没有自动维护的string类型的东西,所以只能以原始的字节串(虽然一般都称为“字符串”,但是考虑到“字符”是有“编码”的,所以只能称为“字节串”)数组的形式存放,参数argc实际上就是字节串数组第一维的个数。
下面是一个简单的使用参数的标准C语言程序:
#include<stdio.h> #include<string.h> int main(int argc,char* argv[]) { int i=0; if(argc<1) { printf("Usage sample [...] to use this program!\n"); }else{ for(i=0;i<argc;i++) { printf("arg[%d]:%s\n",i,argv[i]); } } return 0; }
运行起来看看,如果在Dev C++下直接运行你看的是这样的界面
可以看到他的第一个参数就是自己。
可以看到第一个参数永远都是调用者自己的名字,后面才是输入的参数,这也是控制台程序的有用的地方。
在所有具有参数并且要求参数的控制台程序,使用时必入参数,否则argc会小于1,导致无法执行原来程序编程的功能。
例如linux中的lpcrm [-m] [-q] <编号>,这段程序用于移除在系统共享内存段或者消息队列,这些内容是属于《计算机操作系统》的相关内容,如果想要了解的同学可以提前买一本《计算机操作系统》看看,虽然可能看不懂(无奈,似乎操作系统没有图说系列)