理解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);
}

        像这类传入一个函数指针到其他函数,并在这个函数内部通过函数指针调用的方式称为回调函数。在多种实际开发的场合,回调函数都会起巨大作用。
目录
相关文章
|
2月前
|
存储 安全 Java
【Golang】(4)Go里面的指针如何?函数与方法怎么不一样?带你了解Go不同于其他高级语言的语法
结构体可以存储一组不同类型的数据,是一种符合类型。Go抛弃了类与继承,同时也抛弃了构造方法,刻意弱化了面向对象的功能,Go并非是一个传统OOP的语言,但是Go依旧有着OOP的影子,通过结构体和方法也可以模拟出一个类。
206 1
|
3月前
|
存储 C语言
`scanf`是C语言中用于按格式读取标准输入的函数
`scanf`是C语言中用于按格式读取标准输入的函数,通过格式字符串解析输入并存入指定变量。需注意输入格式严格匹配,并建议检查返回值以确保读取成功,提升程序健壮性。
1026 0
|
5月前
|
安全 C语言
C语言中的字符、字符串及内存操作函数详细讲解
通过这些函数的正确使用,可以有效管理字符串和内存操作,它们是C语言编程中不可或缺的工具。
333 15
|
6月前
|
存储 C语言
指针的函数传参的详细讲解(一)
本文介绍了计算机内存管理与C语言中指针的基本概念及应用。从内存单元的划分到指针的定义,解释了指针作为地址的作用及其数据类型特性。文章通过代码示例详细说明了一级指针、二级指针的使用方法,以及`void*`指针的特点和限制。此外,还探讨了指针运算规则、函数指针传参解引用的原理,并结合链表实例分析了一级与二级指针在实际场景中的区别。最后附带两道指针练习题,帮助读者巩固理解。
150 0
|
10月前
|
人工智能 Java 程序员
一文彻底搞清楚C语言的函数
本文介绍C语言函数:函数是程序模块化的工具,由函数头和函数体组成,涵盖定义、调用、参数传递及声明等内容。值传递确保实参不受影响,函数声明增强代码可读性。君志所向,一往无前!
431 1
一文彻底搞清楚C语言的函数
|
11月前
|
C语言
【C语言程序设计——函数】亲密数判定(头歌实践教学平台习题)【合集】
本文介绍了通过编程实现打印3000以内的全部亲密数的任务。主要内容包括: 1. **任务描述**:实现函数打印3000以内的全部亲密数。 2. **相关知识**: - 循环控制和跳转语句(for、while循环,break、continue语句)的使用。 - 亲密数的概念及历史背景。 - 判断亲密数的方法:计算数A的因子和存于B,再计算B的因子和存于sum,最后比较sum与A是否相等。 3. **编程要求**:根据提示在指定区域内补充代码。 4. **测试说明**:平台对代码进行测试,预期输出如220和284是一组亲密数。 5. **通关代码**:提供了完整的C语言代码实现
261 24
|
11月前
|
存储 C语言
【C语言程序设计——函数】递归求斐波那契数列的前n项(头歌实践教学平台习题)【合集】
本关任务是编写递归函数求斐波那契数列的前n项。主要内容包括: 1. **递归的概念**:递归是一种函数直接或间接调用自身的编程技巧,通过“俄罗斯套娃”的方式解决问题。 2. **边界条件的确定**:边界条件是递归停止的条件,确保递归不会无限进行。例如,计算阶乘时,当n为0或1时返回1。 3. **循环控制与跳转语句**:介绍`for`、`while`循环及`break`、`continue`语句的使用方法。 编程要求是在右侧编辑器Begin--End之间补充代码,测试输入分别为3和5,预期输出为斐波那契数列的前几项。通关代码已给出,需确保正确实现递归逻辑并处理好边界条件,以避免栈溢出或结果
645 16
|
11月前
|
存储 编译器 C语言
【C语言程序设计——函数】分数数列求和2(头歌实践教学平台习题)【合集】
函数首部:按照 C 语言语法,函数的定义首部表明这是一个自定义函数,函数名为fun,它接收一个整型参数n,用于指定要求阶乘的那个数,并且函数的返回值类型为float(在实际中如果阶乘结果数值较大,用float可能会有精度损失,也可以考虑使用double等更合适的数据类型,这里以float为例)。例如:// 函数体代码将放在这里函数体内部变量定义:在函数体中,首先需要定义一些变量来辅助完成阶乘的计算。比如需要定义一个变量(通常为float或double类型,这里假设用float。
534 3
|
10月前
|
存储 人工智能 Java
一文轻松拿捏C语言的指针的基础使用
本文介绍了C语言中的指针概念,包括直接访问和间接访问内存的方式、指针变量的定义与使用、取址运算符`&`和取值运算符`*`的应用,帮助读者深入理解指针这一C语言的核心概念。君志所向,一往无前!
202 0
|
11月前
|
存储 算法 安全
【C语言程序设计——函数】分数数列求和1(头歌实践教学平台习题)【合集】
if 语句是最基础的形式,当条件为真时执行其内部的语句块;switch 语句则适用于针对一个表达式的多个固定值进行判断,根据表达式的值与各个 case 后的常量值匹配情况,执行相应 case 分支下的语句,直到遇到 break 语句跳出 switch 结构,若没有匹配值则执行 default 分支(可选)。例如,在判断一个数是否大于 10 的场景中,条件表达式为 “num> 10”,这里的 “num” 是程序中的变量,通过比较其值与 10 的大小关系来确定条件的真假。常量的值必须是唯一的,且在同一个。
413 2