📎

Pointer

Arguments

  • C语言源程序经编译和连接处理,生成可执行程序(例如test.exe)后,才能运行。
  • 在DOS环境的命令窗口中,输入可执行文件名,就以命令方式运行该程序。
  • 输入命令时,在可执行文件(命令)名的后面可以跟一些参数,这些参数被称为命令行参数
test world (test是命令名,world是命令行参数)
 
命令行的一般形式为: 命令名  参数1 参数2 … 参数n
📎
命令名和各个参数之间用空格分隔,也可以没有参数
使用命令行的程序不能在编译器中执行,需要将源程序经编译、链接为相应的命令文件(一般以.exe为后缀),然后回到命令行状态,再在该状态下直接输入命令文件名。
带参数的main()函数格式:
int main(int argc, char *argv[ ])
{
......
}
第1个参数argc接收命令行参数(包括命令名)的个数;第2个参数argv接收以字符串常量形式存放的命令行参数(包括命令名本身也作为一个参数)。
e.g.
notion image
运行结果
在命令行状态下输入:
echo  How  are  you?
输出:How are you?
 

Pointer as the return value of a function

返回值

📎
如果有函数char *func(char *p, char ch),则下面说法错误的是( )。
A.函数返回一个字符指针
B.可以通过语句return NULL;返回函数结果
C.可以通过语句return -1;返回函数结果
D.可以通过语句return p;返回函数结果
在C语言中,如果一个函数的返回类型是指针类型,确实可以返回 0。在这种情况下,0 被解释为一个空指针(NULL 指针),表示指针不指向任何有效的内存地址。
📎
题目:C语言中 如果函数的返回类型是指针,则可以返回函数内部任意变量的地址。
F
不能返回在函数内部定义的局部数据对象的地址,这是因为所有的局部数据对象在函数返回时就会消亡,其值不再有效。
返回指针的函数一般都返回全局数据对象或主调函数中数据对象的地址

Pointer to function

每个函数都占用一段内存单元,它们有一个入口地址(起始地址)
在C语言中,函数名代表函数的入口地址。
我们可以定义一个指针变量,接收函数的入口地址,让它指向函数,这就是指向函数的指针,也称为函数指针
通过函数指针可以调用函数,它也可以作为函数的参数。
notion image

函数指针的定义

函数指针定义的一般格式为: 类型名  (*变量名) ( 参数类型表);
类型名指定函数返回值的类型,变量名是指向函数的指针变量的名称。
e.g.
int (*funptr) ( int, int);
定义一个函数指针funptr,它可以指向有两个整型参数且返回值类型为int的函数。

通过函数指针调用函数

通过函数指针调用函数的一般格式为: (*函数指针名) (参数表)
e.g.
📎
int fun (int x, int y); //定义函数
int (*funptr) (int, int); //定义函数指针
funptr = fun;
(*funptr)(3 , 5);

函数指针作为函数的参数

C语言的函数调用中,函数名或已赋值的函数指针也能作为实参,此时,形参就是函数指针,它指向实参所代表函数的入口地址。
e.g.
📎
f(int (*funptr)(int, int))
{…}
void main()
{ …
int (*funptr)(int, int);
funptr = fun;
f( funptr );
}

下面给出一个应用实例

本例由ChatGPT-o1提供
小注:
上述示例在使用函数指针在调用函数时,使用了直接使用函数指针的方法:
而上文中提到的则是采用显式解引用函数指针的方法,在本例中即:
经过实践,两种方法都是合法且效果相同的
这是由于C语言中函数指针和函数名之间的隐式转换机制,以及C语言的语法规则使然。
a. 函数名隐式转换为指针
在C语言中,函数名在大多数表达式中会隐式地转换为指向该函数的指针。这意味着:
两者是等价的。
b. 函数指针的调用
当你使用函数指针进行调用时,C允许你直接使用函数指针来调用函数,而无需显式解引用。这是因为函数调用操作符 () 的优先级比较高,并且C语言中的函数调用语法自动处理了指针的解引用。
具体来说:
  • op(arr[i])
    • 这里,op 被视为一个函数指针,op(arr[i]) 实际上是调用 op,即解引用后再调用。
    • 编译器自动将 op 解释为 (*op),因此等同于 (*op)(arr[i])
  • (*op)(arr[i])
    • 这里,op 显式地解引用函数指针,得到一个函数,然后调用它。
因此,两者在语义上是相同的,编译器会将它们转换为相同的操作。
Loading...