理解C语言——从小菜到大神的晋级之路(13)——进一步讨论函数与指针

简介: 本期视频:点击这里 1、main函数的参数         在我们编写的简单程序中,main函数常常是不带参数的。比如这样一个简单的程序,给main函数添加参数似乎也没什么意义: int main(){ printf("Hello world!\n");}        而实际上,main函数是可以添加参数的,而且在实际应用中也非常普遍。
本期视频:点击这里


1、main函数的参数



        在我们编写的简单程序中,main函数常常是不带参数的。比如这样一个简单的程序,给main函数添加参数似乎也没什么意义:
int main()
{
     printf("Hello world!\n");
}

        而实际上,main函数是可以添加参数的,而且在实际应用中也非常普遍。main函数完整的原型如下所示:
int main(int argc, char **argv);

        主函数的参数的传入,不是在我们所编写的C程序代码中实现的,而是在运行C程序时,通过命令行传入。在程序运行的过程中,命令行的数据将会从main函数参数中传入程序代码中。其中,argc表示命令行参数的个数,argv以字符串数组的形式表示每一个命令行参数。需要注意的是这两个参数都包含可执行程序程序本身。比如如果我们编译出来的可执行程序名称为hello.exe,那么在命令行或批处理文件中写入以下命令:
hello.exe name1 name2

        在这种情况下,argc为3,表示整个命令行有3个参数;argv表示保存每个命令行参数的数组, argv[0] 、argv[1]、 argv[2]分别表示"hello.exe"、"name1"和"name2"。

        main函数的参数在实际应用中比较常用。例如很多程序可能需要比较复杂的配置数据,这些配置数据通常写入一个配置文件中。在程序调用的时候,可以通过命令行参数传入配置文件的地址,在程序中通过命令行参数获取的地址来打开和解析配置文件。


2、指向函数的指针



        在前面的内容中,我们讨论的指针变量指的是一种保存了数据内存地址的数据类型。通过指针变量保存的地址,我们可以获取目标内存中保存的数据。指针变量通常在函数参数传递、连续内存数据遍历等场合可以发挥重大作用。在定义时,需要根据所指向的内存中保存的数据类型来定义指针变量的类型。如我们需要一个执行int型数据的指针变量pInt,那么就应定义int *pInt。

        事实上,指针变量不仅仅可以指向各种数据,还可以指向某个函数。在我们定义一个函数的时候,实际上函数名就代表了这个函数的入口地址,因此可以定义一种指向该类型函数的指针变量带指向函数的地址。
假设我们定义以下函数:
int GoodMorning(char *pName)
{
   if(NULL == pName)
   {
     printf("Please enter the name.\n");
     return 0;
   }
   else
   {
     printf("Good morning, %s.\n", pName);
   }
   return 1;
}

        众所周知,函数的调用格式为:函数名(实参列表)。在编译时,函数名实际上会被编译器转换为一个函数指针指向实际的地址。在程序中,函数名本身赋予指向函数的指针时就可以认为是函数的地址所在。我们定义一个指向函数的指针,并指向上述函数:
int (* greetings)( char * pName ) = GoodMorning ;
//等价于int (* greetings)( char * pName ) = &GoodMorning ;

        然后,我们可以通过函数指针调用该函数, 其功能和 GoodMorning ( "Jerry" )相同。
greetings ( "Jerry" );

        需要注意的是,函数指针的类型必须与目标函数完全一致,包括返回值类型和参数个数、类型。如果出现不一致将无法指向。


3、函数指针作为参数传递



        函数名以及指向函数的指针可以作为参数传递到另一个函数内。事实上,作为参数的函数指针与其他类型的变量指针并没有本质的区别,都是某一段内存的地址。在前面的内容中,由于指针类型是某种变量类型(比如int *),这段内存中的数据都将按照这种变量来处理;如果这个指针是某个函数类型,那么这段内存中的数据就被当做函数的代码,可以对其进行调用。

        我们把上述程序稍作修改:
void greetings(int (* grt_func)( char * pName ), char * pName )
{
      grt_func(pName);
}

        像这类传入一个函数指针到其他函数,并在这个函数内部通过函数指针调用的方式称为回调函数。在多种实际开发的场合,回调函数都会起巨大作用。
目录
相关文章
|
1月前
|
C语言
【c语言】指针就该这么学(1)
本文详细介绍了C语言中的指针概念及其基本操作。首先通过生活中的例子解释了指针的概念,即内存地址。接着,文章逐步讲解了指针变量的定义、取地址操作符`&`、解引用操作符`*`、指针变量的大小以及不同类型的指针变量的意义。此外,还介绍了`const`修饰符在指针中的应用,指针的运算(包括指针加减整数、指针相减和指针的大小比较),以及野指针的概念和如何规避野指针。最后,通过具体的代码示例帮助读者更好地理解和掌握指针的使用方法。
49 0
|
14天前
|
C语言
c语言调用的函数的声明
被调用的函数的声明: 一个函数调用另一个函数需具备的条件: 首先被调用的函数必须是已经存在的函数,即头文件中存在或已经定义过; 如果使用库函数,一般应该在本文件开头用#include命令将调用有关库函数时在所需要用到的信息“包含”到本文件中。.h文件是头文件所用的后缀。 如果使用用户自己定义的函数,而且该函数与使用它的函数在同一个文件中,一般还应该在主调函数中对被调用的函数做声明。 如果被调用的函数定义出现在主调函数之前可以不必声明。 如果已在所有函数定义之前,在函数的外部已做了函数声明,则在各个主调函数中不必多所调用的函数在做声明
29 6
|
1月前
|
存储 C语言 C++
如何通过指针作为函数参数来实现函数的返回多个值
在C语言中,可以通过将指针作为函数参数来实现函数返回多个值。调用函数时,传递变量的地址,函数内部通过修改指针所指向的内存来改变原变量的值,从而实现多值返回。
|
27天前
|
存储 算法 程序员
C语言:库函数
C语言的库函数是预定义的函数,用于执行常见的编程任务,如输入输出、字符串处理、数学运算等。使用库函数可以简化编程工作,提高开发效率。C标准库提供了丰富的函数,满足各种需求。
|
1月前
|
机器学习/深度学习 C语言
【c语言】一篇文章搞懂函数递归
本文详细介绍了函数递归的概念、思想及其限制条件,并通过求阶乘、打印整数每一位和求斐波那契数等实例,展示了递归的应用。递归的核心在于将大问题分解为小问题,但需注意递归可能导致效率低下和栈溢出的问题。文章最后总结了递归的优缺点,提醒读者在实际编程中合理使用递归。
61 7
|
1月前
|
存储 编译器 程序员
【c语言】函数
本文介绍了C语言中函数的基本概念,包括库函数和自定义函数的定义、使用及示例。库函数如`printf`和`scanf`,通过包含相应的头文件即可使用。自定义函数需指定返回类型、函数名、形式参数等。文中还探讨了函数的调用、形参与实参的区别、return语句的用法、函数嵌套调用、链式访问以及static关键字对变量和函数的影响,强调了static如何改变变量的生命周期和作用域,以及函数的可见性。
30 4
|
1月前
|
C语言
【c语言】指针就该这么学(3)
本文介绍了C语言中的函数指针、typedef关键字及函数指针数组的概念与应用。首先讲解了函数指针的创建与使用,接着通过typedef简化复杂类型定义,最后探讨了函数指针数组及其在转移表中的应用,通过实例展示了如何利用这些特性实现更简洁高效的代码。
18 2
|
1月前
|
存储 搜索推荐 C语言
如何理解指针作为函数参数的输入和输出特性
指针作为函数参数时,可以实现输入和输出的双重功能。通过指针传递变量的地址,函数可以修改外部变量的值,实现输出;同时,指针本身也可以作为输入,传递初始值或状态。这种方式提高了函数的灵活性和效率。
|
1月前
|
C语言
如何避免 C 语言中的野指针问题?
在C语言中,野指针是指向未知内存地址的指针,可能引发程序崩溃或数据损坏。避免野指针的方法包括:初始化指针为NULL、使用完毕后将指针置为NULL、检查指针是否为空以及合理管理动态分配的内存。
|
1月前
|
C语言
C语言:哪些情况下会出现野指针
C语言中,野指针是指指向未知地址的指针,通常由以下情况产生:1) 指针被声明但未初始化;2) 指针指向的内存已被释放或重新分配;3) 指针指向局部变量,而该变量已超出作用域。使用野指针可能导致程序崩溃或不可预测的行为。
下一篇
无影云桌面