函数参数调用指针、结构体

一、函数调用指针时
void main(void)
{
int a,int b;
a=5;
b=3;
fun(&a,&b);
}
void fun(*p1,*p2)
{
int c;
c=*p1;
*p1=*p2;
*p2=c;
}
1、此时函数声明参数是两个指针,因此主函数中函数的调用参数应该输入两个指针,就是a,b的地址。
2、再次强调,需要改变输入参数的值时函数才需要调用该指针,就是说fun(x,y) fun(结构1),需要改变调用参数的值时,该参数采用指针表示(此处指想要改变的是普通变量,而不是改变指针变量)

二、函数调用结构体
1、结构体、实例、指向结构的指针
结构体的实例相当于一个变量,让指针指向该结构体的实例时可以这么写
sturct stu{
char names;
};
sturct stu *p1; 申明了指向该结构的指针p1,但是该指针并未初始化,还不能使用
struct stu s1;
p1=&s1; 创建了实例后就可以让指针指向实例了

或者
struct stu{
char name;
};
struct stu *p1;
p1=(stu*)malloc(sizeof(struct stu)); 此处给指针分配空间,最后记得free

2、函数调用
定义时
void fun(stu *p1,stu p2)
main中 stu s1,s2; 创建两个实例
调用时fun(&s1,s2)

这里有个重点,为啥同样是实例,两个申明时一个是申明指针,一个就是申明实例呢?答案和本文第一部分函数调用指针参数一样,只有在想改变参数的值时才将参数设为指针类型,否则就是本来的类型。比如实例s1,我的函数f1想要在s1中插入值,就更改了s1,就要申明f1(*s1);我的函数f2想要把s1中的值读出来,不更改s2,就不需要指针作为参数,就是f2(s1).

<think>好的,我现在要解释一下函数指针参数为结构体的概念。首先,我需要明确什么是函数指针,以及结构体作为参数时的用法。 函数指针是指向函数指针变量,它可以用来调用函数或者作为参数传递。结构体是一种用户自定义的数据类型,可以包含多个不同类型的数据成员。当函数指针的参数是结构体时,意味着这个函数接受一个结构体实例作为参数,或者返回结构体。 接下来,我需要考虑用户可能的疑问。比如,如何定义这样的函数指针,如何将结构体作为参数传递,以及实际应用中的例子。可能需要分步骤说明,比如先定义结构体,再声明函数指针,然后展示如何赋值和使用。 同时,要确保示例代码符合LaTeX格式要求,行内公式用$...$,独立公式用$$...$$。不过这里主要是代码示例,可能不需要太多数学公式,但如果有涉及运算的地方需要注意。 需要检查是否有语法错误,比如结构体定义是否正确,函数指针的声明是否正确。例如,结构体可能需要用typedef来简化,函数指针的参数类型要与实际函数匹配。 另外,用户可能需要了解为什么需要这样的用法,比如在回调函数中传递结构体数据,或者在多线程编程中传递参数。可以举一个实际应用的场景,比如排序函数中比较结构体成员。 可能还需要注意指针的使用,比如传递结构体指针而不是整个结构体,以提高效率。这时候函数指针的参数应该是结构体指针类型,即struct MyStruct *。 最后,总结一下关键点,确保回答结构清晰,逐步引导用户理解概念,并提供正确的代码示例。</think>函数指针参数为结构体时,通常用于需要将结构体数据与函数操作结合的场景。以下是逐步说明: --- ### 一、基本概念 1. **结构体** 结构体是自定义的复合数据类型,可包含多个成员变量: ```c typedef struct { int id; float value; } MyStruct; ``` 2. **函数指针** 函数指针指向函数入口地址,定义格式为: `返回类型 (*指针名)(参数列表)` 例如:`void (*func_ptr)(MyStruct);` --- ### 二、函数指针参数为结构体的定义 #### 示例1:直接传递结构体 ```c // 定义结构体 typedef struct { int x; int y; } Point; // 定义函数指针类型(参数为Point结构体) void (*DrawCallback)(Point p); // 实际函数 void DrawPoint(Point p) { printf("Drawing at (%d, %d)\n", p.x, p.y); } // 使用 int main() { DrawCallback = DrawPoint; Point pt = {10, 20}; DrawCallback(pt); // 输出:Drawing at (10, 20) return 0; } ``` #### 示例2:传递结构体指针(更高效) ```c typedef struct { char name[50]; int age; } Person; // 函数指针类型(参数为Person指针) void (*PrintInfo)(Person*); void PrintPerson(Person *p) { printf("Name: %s, Age: %d\n", p->name, p->age); } int main() { PrintInfo = PrintPerson; Person user = {"Alice", 30}; PrintInfo(&user); // 输出:Name: Alice, Age: 30 return 0; } ``` --- ### 三、典型应用场景 1. **回调函数** 在事件驱动编程中,通过结构体传递上下文数据: ```c typedef struct { int eventType; void *data; } Event; void (*EventHandler)(Event*); void HandleClick(Event *e) { printf("Event type %d triggered\n", e->eventType); } int main() { EventHandler = HandleClick; Event clickEvent = {1, NULL}; EventHandler(&clickEvent); // 输出:Event type 1 triggered return 0; } ``` 2. **多态与策略模式** 通过函数指针动态选择算法: ```c typedef struct { int a; int b; int (*Operation)(int, int); // 函数指针作为结构体成员 } Calculator; int Add(int x, int y) { return x + y; } int Subtract(int x, int y) { return x - y; } int main() { Calculator calc; calc.a = 5; calc.b = 3; calc.Operation = Add; printf("5 + 3 = %d\n", calc.Operation(5, 3)); // 输出:8 calc.Operation = Subtract; printf("5 - 3 = %d\n", calc.Operation(5, 3)); // 输出:2 return 0; } ``` --- ### 四、注意事项 1. **内存管理** 若结构体包含动态分配的内存(如指针),需确保生命周期有效。 2. **类型匹配** 函数指针的参数类型必须与实际函数严格匹配,否则会导致未定义行为。 3. **可读性** 使用`typedef`简化复杂声明: ```c typedef void (*Callback)(MyStruct*); Callback myCallback; // 代替 void (*myCallback)(MyStruct*); ``` --- ### 五、总结 函数指针参数为结构体的核心价值在于: - **灵活性**:将数据与操作解耦,支持动态行为 - **封装性**:通过结构体打包多个相关参数 - **高效性**:传递指针避免结构体复制的开销 掌握此技术可显著提升代码模块化程度,适用于驱动开发、框架设计等场景。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值