main函数的定义形式
main函数可以不带参数,也可以带参数,这个参数可以认为是 main函数的形式参数。C语言规定main函数的参数只能有两个,习惯上这两个参数写为argc和argv。所以C99标准中规定只有以下两种定义方式是正确的:
int main(void) //无参形式
int main(int argc, char *argv[]) //有参形式
当然有参形式可以进行演变,所以下面的写法也是正确的(同时变量名是可以更换的):
int main(int argc, char **argv) //有参的另一种形式
为什么可以演变?
根据前面的一些介绍,可以看出终端传递给main函数的参数是一个二维数组的首地址,这个二维数组的每一维都是一个字符串。既然这样的话就比较好理解了,当我们在调用函数的时候如果传递的是数组首地址的话,那么传递过去的参数会进行退化为指针,比如传递的是int型数组a,接收方接收到的就是一个int *类型的指针,所以这里也是一样,终端传递给main函数的二维数组也会退化成二级指针即char **。
main函数参数的值
再来说一说main函数的参数的值,假设你在终端上运行./test hello world
那么argc和argv的值分别为多少呢?argc的值为3,而argv里面的字符串也为3个,这是因为你在运行C程序的时候系统默认会把可运行文件的名字也作为一个参数传递给main函数,并且参数的第一个就是可运行文件的名字(会包含详细路径)。
使用main函数的参数
基于上面的分析,下面继续看看如何使用main函数传递过来的参数,下面一段程序片段是打印出main函数接收到的参数:
for(i=0; i < argc; i++)
printf("%s\n", *argv++);
这个是没有问题的,另一种操作方式是:
for(i=0; i < argc; i++)
printf("%s\n", argv[i]);
但是最后的一种方式就是错误的:
for(i=0; i < argc; i++)
printf("%s\n", *argv[i]);
我最开始尝试的就是这种方式,居然出现错误了,这是为何?argv是一个指针数组名,那么argv[0]、argv[1]这就是一个指针的值啊,然后再使用*p的方式取用里面的数据,怎么会出错呢?最后终于想明白,这是打印的字符串,所以只需要传递数组名或者指针值就可以了!比如定义了
char *p="Hello world.";
如果要打印这个字符串当然使用的是
printf("%s\n", p);
如果打印*p的话,岂不是只取了字符串中的一个H字符,打印当然是会报错的。
相关文章
- C语言中的main函数的参数解析
- C语言中的main函数以及main函数是如何被调用的
- C#委托(delegate)的常用方式- 委托的定义 // 委托的核心是跟委托的函数结构一样 public delegate string SayHello(string c); public delegate string SayHello(string c);:定义了一个公共委托类型 SayHello,该委托接受一个 string 类型的参数 c,并返回一个 string 类型的值。 Main 方法 static void Main(string args) { // 本质上其实就是把方法当作委托的参数 SayHello sayC = new SayHello(SayChinese); Console.WriteLine(sayC("欢迎大家")); SayHello sayE = new SayHello(SayEgnlish); Console.WriteLine(sayE("Welcome to")); // 简单的写法:必须类型一样 SayHello s1 = SayChinese; SayHello s2 = SayEgnlish; Console.WriteLine(s1("好好好")); Console.WriteLine(s2("Gooood")); // 最推荐 SayHello ss1 = con => con; Console.WriteLine(ss1("niiiice")); // 匿名委托:一次性委托 SayHello ss3 = delegate(string s) { return s; }; Console.WriteLine(ss3("说中国话")); } 常规实例化委托 SayHello sayC = new SayHello(SayChinese);:创建了一个 SayHello 委托的实例 sayC,并将 SayChinese 方法作为参数传递给委托的构造函数。 Console.WriteLine(sayC("欢迎大家"));:通过委托实例调用 SayChinese 方法,并输出结果。 同理,SayHello sayE = new SayHello(SayEgnlish); 和 Console.WriteLine(sayE("Welcome to")); 是对 SayEgnlish 方法的委托调用。 简化的委托赋值方式 SayHello s1 = SayChinese; 和 SayHello s2 = SayEgnlish;:当委托类型和方法签名一致时,可以直接将方法赋值给委托变量,无需使用 new 关键字。 Console.WriteLine(s1("好好好")); 和 Console.WriteLine(s2("Gooood"));:通过委托实例调用相应的方法。 使用 Lambda 表达式实例化委托 SayHello ss1 = con => con;:使用 Lambda 表达式创建委托实例 ss1,con => con 表示接受一个参数 con 并返回该参数本身。 Console.WriteLine(ss1("niiiice"));:通过委托实例调用 Lambda 表达式。 匿名委托 SayHello ss3 = delegate(string s) { return s; };:使用匿名委托创建委托实例 ss3,delegate(string s) { return s; } 是一个匿名方法,直接在委托实例化时定义了方法体。 Console.WriteLine(ss3("说中国话"));:通过委托实例调用匿名方法。 委托引用的方法定义 public static string SayChinese(string content) { return content; } public static string SayEgnlish(string content) { return content; } public static string SayChinese(string content) 和 public static string SayEgnlish(string content):定义了两个静态方法,分别接受一个 string 类型的参数 content,并返回该参数本身。这两个方法的签名与 SayHello 委托一致,可以被 SayHello 委托引用。 常规的委托实例化、简化的赋值方式、Lambda 表达式和匿名委托。委托在 C# 中是一种强大的机制,它允许将方法作为参数传递,实现了代码的灵活性和可扩展性。
- C语言中没有main函数生成可执行程序的几种方法
- c语言main函数返回值、参数详解(返回值是必须的,0表示正常退出)
- C/C++语言中的函数参数传参三种对比
- C语言中可变参数的函数(三个点,“...”)
- C语言带参数的main()函数
- C语言中函数参数为什么是由右往左入栈的?
- c语言中printf()函数中的参数计算顺序