下面的第一个程序使用指针成功地调用了一个函数。我现在尝试使用结构体数组来实现相同的机制。最后一行(注解掉)将不起作用,我没有看到任何差异。我做错了什么?
有没有可能我在第二个程序中把这一行的格式搞错了?
- void(func_ptr)(struct book,int)= printBook;
我使用了这个格式:第一个月
这个管用
// C call function using pointer
#include <stdio.h>
#include <string.h>
void func(int a) { // normal function
printf("Value of a is %d\n", a);
}
int main() {
void (*func_ptr)(int) = func; // assign ptr to func address
func_ptr(10); // call func
return 0;
}
字符串
这行不通
// Looks the same but does not work
#include <stdio.h>
#include <string.h>
// data structure
struct book { // struct data
int book_id; // book id
int (*prtFunc) ( struct book ); // eventually, addr of print function
char title[50]; // book title
char author[50]; // book author
};
struct book arBookList[10];
void printBook ( struct book arBookList[], int id ) { // test struct access
printf ( "book_id : %d\n", arBookList[id].book_id );
printf ( "func addr : %p\n", arBookList[id].prtFunc ); // eventually this will call function
printf ( "title : %s\n", arBookList[id].title ); // string data test
printf ( "author : %s\n", arBookList[id].author ); // string
printf ( "\n" );
}
int main ( ) {
arBookList[0].book_id = 0 ;
arBookList[0].prtFunc = printBook;
strcpy ( arBookList[0].title, "This Little Piggy" );
strcpy ( arBookList[0].author, "Bad Wolf" );
printBook (arBookList, 0 ); // show data using function call
arBookList[1].book_id = 1 ;
arBookList[1].prtFunc = printBook;
strcpy ( arBookList[1].title, "Mary Had a Lamb" );
strcpy ( arBookList[1].author, "Snow Fleece" );
printBook (arBookList, 1 ); // show data using function call
// call function using pointer
void (*func_ptr)(struct book, int) = printBook; // assign ptr to func address
func_ptr (arBookList, 1 ); // <--- does not work, why ???
// commenting out the above line compiles ok
// but it looks ok to me except for different call parameters
return 0;
}
型
**供将来参考:**通过下面的'O'的更正列表,我达到了我的最终目标,即能够在struct中调用保存的函数指针来调用函数(在本例中为printBook),如下所示:arBookList[1].prtFunc (arBookList, 1 );
个
2条答案
按热度按时间icnyk63a1#
对于函数指针,参数错误。你传递了一个指针,它需要的是结构体。
修正后的程序:
字符串
而且你的函数指针在结构中的类型也不对。
https://godbolt.org/z/5E1E8v7j3
4sup72z82#
在
struct book
中,您将prtFunc
声明为字符串
在
main
中,您在型
但
printBook
是型
因此,acual参数与声明不匹配。
另一问题
有点离题,但如果函数对所有书籍都相同,则不应在阵列中的每个
book
中复制其地址。示例:使用集合而非数组
型
这样,我们就有了一个集合
Books
,其中包含size
和limit
。也是一个指向打印一本书的函数的指针。而且书都在struct
里面,所以你可以把它作为一个整体来使用。您的测试集合可以用现代的方式声明为
型
这更易于阅读和测试。
print_book
的一个版本型
单个
printf
(或puts
)的读取和键入速度更快、更容易打印所有图书
如果有一个函数可以方便地打印完整的
Books
结构:型
由于它在
Books
结构中使用了嵌入式指针,因此只需更改结构中的指针就可以轻松地更改样式使用2个函数
型
在这里,我们调用
print_book
来打印每本书,使用集合中的指针,按名称和引用来打印。然后打印集合。完整的示例
型
示例的输出
型
在这个例子中
Books
中的指针Books
内的函数指针发生变化带类的C:使用函数指针转换
Container
泛型下面是上一个示例中 * 集合 * 的
struct
:型
它解决了很多问题,因为它可以作为一个整体来对待,并封装了当前和总大小限制。
但是:
Book
分配了内存,则无法释放它。struct
中容器的代码最好独立于物料的代码。
示例:更通用的容器
确定是物品清单。但也可能是链表、集合、队列、数组......
C++
将其称为 * 容器 *。java
和其他人称之为 * 集合 *。考量
型
现在,我们有了一个指向项目的指针数组,并且:
但集装箱却不知道它的实际内容:是容器的用户生成代码,而容器只是保存函数指针。
甚至不需要重新编译
container.c
的代码型
最小函数集:
型
这是写一个例子的最低限度,就像下面这个例子。
在
item.h
中将Book
作为Item
型
由于函数指针的存在,容器代码的更改不会导致物料代码的更改。在
C++
中,它们将被称为Item
的 * 复制构造函数 、 析构函数 * 和 * 运算符<<重载 *。执行:
Book
个项目. h
型
函数现在接受并返回
void
,但Book
有一个定义,因此所有函数都可以根据需要转换指针。这与qsort
中使用的方法(例如,从stdlib
开始)相同。例如java
或javascript
中的 * 回调 *。请注意,现在
Book
使用指向title
和author
的指针,并有一个新的页数字段。因此,内存被分配到所需的确切大小,而不是第一个示例中的固定数组。问题是,现在要销毁容器,代码必须知道如何释放这些字段和
Book
本身。这里是一个 callback(函数指针)的用法和需要。item.c
的简单实现型
没有对
Container
的引用:仅包含item.h
以获得Book
和函数原型。请注意,添加了
create_book()
,这是一个方便的 * 工厂函数 *,每次调用它时都会生成一本新书。这种方法很容易在没有输入文件的情况下使用任意数量的项进行测试。泛型
Container
的代码请注意,该容器甚至不包括
item.h
container.h
的一个字符串型
而
Container
现在是指向项的指针数组。任意项,因为用户在调用ctn_create()
时传递了函数的地址。通过这种方式,程序可以轻松地管理一组项目,甚至是不同的项目。
container.c
个字符型
main.c
进行简单测试型
注一:
型
在这里使用
books->show
的要点是它封装了行为,作为Python
或java
或C++
中的对象:通过更改此设置,下一次对cnt_show
的调用将继承新的打印布局:见下面的程序输出注2:
通过从
cnt_destroy
返回NULL
,容器的指针在同一行代码中无效:没有办法有一个无效的指针。这很好,所以下一行对ctn->show
的调用不会得到已经删除的容器的指针。示例输出
代码在https://github.com/ARFNeto-CH/soc23-0720-example上