当前位置:首页 » 编程语言 » c语言函数指针问题解决方法
扩展阅读
webinf下怎么引入js 2023-08-31 21:54:13
堡垒机怎么打开web 2023-08-31 21:54:11

c语言函数指针问题解决方法

发布时间: 2022-08-05 08:53:21

c语言函数指针问题

typedef struct StateStruct {
void (*FuncPtr)( void * ptr ) f;
}SS;
//定义了一个新的类型,这个类型是个结构体,类型名是SS
//下面声明一个SS类型的变量
SS s;
//s就是一个SS类型的变量

void (*FuncPtr)( void * ptr );
//是一个类型名,类型是FuncPtr,这是一个函数指针类型,这个函数指针类型是返回值是void,接受一个void*的指针地址的参数。
//一般使用typedef语法来用
typedef void (*FuncPtr)( void * ptr );
typedef struct StateStruct {
FuncPtr fp;
}SS;

void f(void *ptr)
{
}
//函数f就是一个funcPtr类型的函数。
//可以以下面的方法赋值:
s.fp = f;

const SS St_StateInit = { (void (*)(void *))State_Init };
//用下面的写法会好看很多
const SS St_StateInit = { (FuncPtr)State_Init };
//这是用State_Init来初始化fp的值。

Ⅱ C语言指向函数指针问题

#include
<stdio.h>
void
main()
{
int
max(int
,int
);
int
(*p)(int
,int);
p=max;
//此处利用
p=max是正确的指向函数的指针的用法,p指向max的入口地址
//此处用*p=max得到相同结论,为什么呢?因为你这样赋值之后*p的内容就是max
//所以在执行(*p)(q,w)它时其实是执行的(max)(q,w),如果是p=max此时执行(*p)(q,w)是等价于执行max(q,w)。
int
q,w;
printf("please
input
the
two
numbers:\n");
scanf("%d%d",&q,&w);
printf("the
larger
number
is:%d",(*p)(q,w));
}
////////////////////////////////////
int
max(int
a,int
b)
{
if(a>b)
return
a;
else
return
b;
}

Ⅲ C语言中函数指针用法

函数在内存中有一个物理位置,而这个位置是可以赋给一个指针的。一零点函数的地址就是该函数的入口点。因此,函数指针可被用来调用一个函数。函数的地址是用不带任何括号或参数的函数名来得到的。(这很类似于数组地址的得到方法,即,在只有数组名而无下标是就得到数组地址。)

怎样说明一个函数指针变量呢 ?

为了说明一个变量 fn_pointer 的类型是"返回值为 int 的函数指针", 你可以使用下面的说明语句:

int (*fn_pointer) ();

为了让编译器能正确地解释这句语句, *fn_pointer 必须用括号围起来。若漏了这对括号, 则:

int *fn_pointer ();

的意思完全不同了。fn_pointer 将是一个函数名, 其返回值为 int 类型的指针。

2:函数指针变量

在C语言中规定,一个函数总是占用一段连续的内存区, 而函数名就是该函数所占内存区的首地址。 我们可以把函数的这个首地址 ( 或称入口地址 ) 赋予一个指针变量, 使该指针变量指向该函数。然后通过指针变量就可以找到并调用这个函数。我们把这种指向函数的指针变量称为 " 函数指针变量 " 。

函数指针变量定义的一般形式为:

类型说明符 (* 指针变量名 )();

其中 " 类型说明符 " 表示被指函数的返回值的类型。 "(* 指针变量名 )" 表示 "*" 后面的变量是定义的指针变量。 最后的空括号表示指针变量所指的是一个函数。

例如: int (*pf)();

表示 pf 是一个指向函数入口的指针变量,该函数的返回值 ( 函数值 ) 是整型。

下面通过例子来说明用指针形式实现对函数调用的方法。

int max(int a,int b)

{

if(a>b)return a;

else return b;

}

main()

{

int max(int a,int b);

int(*pmax)();

int x,y,z;

pmax=max;

printf("input two numbers:/n");

scanf("%d%d",&x,&y);

z=(*pmax)(x,y);

printf("maxmum=%d",z);

}

从上述程序可以看出用,函数指针变量形式调用函数的步骤如下:

1>. 先定义函数指针变量,如后一程序中第 9 行 int (*pmax)(); 定义 pmax 为函数指针变量。

2>. 把被调函数的入口地址 ( 函数名 ) 赋予该函数指针变量,如程序中第 11 行 pmax=max;

3>. 用函数指针变量形式调用函数,如程序第 14 行 z=(*pmax)(x,y); 调用函数的一般形式为: (* 指针变量名 ) ( 实参表 ) 使用函数指针变量还应注意以下两点:

a. 函数指针变量不能进行算术运算,这是与数组指针变量不同的。数组指针变量加减一个整数可使指针移动指向后面或前面的数组元素,而函数指针的移动是毫无意义的。

b. 函数调用中 "(* 指针变量名 )" 的两边的括号不可少,其中的 * 不应该理解为求值运算,在此处它只是一种表示符号。

3:指针型函数

前面我们介绍过,所谓函数类型是指函数返回值的类型。 在C语言中允许一个函数的返回值是一个指针 ( 即地址 ) ,这种返回指针值的函数称为指针型函数。

定义指针型函数的一般形式为:

类型说明符 * 函数名 ( 形参表 )

{

…… /* 函数体 */

}

其中函数名之前加了 "*" 号表明这是一个指针型函数,即返回值是一个指针。类型说明符表示了返回的指针值所指向的数据类型。

如:

int *ap(int x,int y)

{

…… /* 函数体 */

}

表示 ap 是一个返回指针值的指针型函数, 它返回的指针指向一个整型变量。下例中定义了一个指针型函数 day_name ,它的返回值指向一个字符串。该函数中定义了一个静态指针数组 name 。 name 数组初始化赋值为八个字符串,分别表示各个星期名及出错提示。形参 n 表示与星期名所对应的整数。在主函数中, 把输入的整数 i 作为实参, 在 printf 语句中调用 day_name 函数并把 i 值传送给形参 n 。 day_name 函数中的 return 语句包含一个条件表达式, n 值若大于 7 或小于 1 则把 name[0] 指针返回主函数输出出错提示字符串 "Illegal day" 。否则返回主函数输出对应的星期名。主函数中的第 7 行是个条件语句,其语义是,如输入为负数 (i<0) 则中止程序运行退出程序。 exit 是一个库函数, exit(1) 表示发生错误后退出程序, exit(0) 表示正常退出。

应该特别注意的是函数指针变量和指针型函数这两者在写法和意义上的区别。如 int(*p)() 和 int *p() 是两个完全不同的量。 int(*p)() 是一个变量说明,说明 p 是一个指向函数入口的指针变量,该函数的返回值是整型量, (*p) 的两边的括号不能少。

int *p() 则不是变量说明而是函数说明,说明 p 是一个指针型函数,其返回值是一个指向整型量的指针,*p 两边没有括号。作为函数说明, 在括号内最好写入形式参数,这样便于与变量说明区别。 对于指针型函数定义,int *p() 只是函数头部分,一般还应该有函数体部分。

main()

{

int i;

char *day_name(int n);

printf("input Day No:/n");

scanf("%d",&i);

if(i<0) exit(1);

printf("Day No:%2d-->%s/n",i,day_name(i));

}

char *day_n

ame(int n)

{

static char *name[]={ "Illegal day",

"Monday",

"Tuesday",

"Wednesday",

"Thursday",

"Friday",

"Saturday",

"Sunday"};

return((n<1||n>7) ? name[0] : name[n]);

}

本程序是通过指针函数,输入一个 1 ~ 7 之间的整数, 输出对应的星期名。指针数组的说明与使用一个数组的元素值为指针则是指针数组。指针数组是一组有序的指针的集合。指针数组的所有元素都必须是具有相同存储类型和指向相同数据类型的指针变量。

指针数组说明的一般形式为: 类型说明符 * 数组名 [ 数组长度 ]

其中类型说明符为指针值所指向的变量的类型。例如: int *pa[3] 表示 pa 是一个指针数组,它有三个数组元素, 每个元素值都是一个指针,指向整型变量。通常可用一个指针数组来指向一个二维数组。 指针数组中的每个元素被赋予二维数组每一行的首地址,因此也可理解为指向一个一维数组。图 6—6 表示了这种关系。

int a[3][3]={1,2,3,4,5,6,7,8,9};

int *pa[3]={a[0],a[1],a[2]};

int *p=a[0];

main()

{

int i;

for(i=0;i<3;i++)

printf("%d,%d,%d/n",a[i][2-i],*a[i],*(*(a+i)+i));

for(i=0;i<3;i++)

printf("%d,%d,%d/n",*pa[i],p[i],*(p+i));

}

本例程序中, pa 是一个指针数组,三个元素分别指向二维数组 a 的各行。然后用循环语句输出指定的数组元素。其中 *a[i] 表示 i 行 0 列元素值; *(*(a+i)+i) 表示 i 行 i 列的元素值; *pa[i] 表示 i 行 0 列元素值;由于 p 与 a[0] 相同,故 p[i] 表示 0 行 i 列的值; *(p+i) 表示 0 行 i 列的值。读者可仔细领会元素值的各种不同的表示方法。 应该注意指针数组和二维数组指针变量的区别。 这两者虽然都可用来表示二维数组,但是其表示方法和意义是不同的

Ⅳ 求教c语言中的函数指针问题

PITE_RET (*PITE_TaskFunction)(PITE_MESSAGE *Msg); ==>

unsigned char (*PITE_TaskFunction)(PITE_MESSAGE *Msg);

上边是函数指针声明的一种:
type (*pointer)(parameter list);
pointer:为函数指针变量名 (这里是:PITE_TaskFunction)
type: 为指向函数的返回值类型 (这里是:unsigned char)
parameter list:为指向函数的参数类型 (这里是:PITE_MESSAGE *Msg)--参数是一个结构体类型的指针。

这样拆开是不是明白一点了。

Ⅳ 关于C语言中指针函数的问题

不行, 原因是found函数已经声明成返回一个int指针的函数了,如果不声明p为指针则在p=founc(a,n)时会因为类型不匹配而报错。两种方法可以解决:1,直接省略掉变量p,在printf语句中直接用printf("%d", *found(a,n));来输出结果;2,修改found函数为:<pre t="code" l="cpp">int found(int b[10], int n)
{
return b[n-1];
}则p可以直接声明为int, 且赋值时用p=found(a,n); 输出时用printf("%d", p);可以看到这样改动的比较多。

Ⅵ c语言,函数里的指针问题

这个其实很好理解
只需要把%s,%c,%p放在一起看
首先%s是最常见的很好理解,就是告诉程序后面的变量是一个字符串,在C语言中也就是字符数组,类型是char*或者char[],换句话说,你告诉程序我会给你一个指针,你去读这个指针指向的值。
然后%c是告诉程序后面的变量是个字符,类型是char,差别已经很明显了,这时候你告诉程序我给你提供一个字符,你给我在%c处打印出来。然而你给的却是一个指针,那程序就直接把你给的指针指向的地址本身当成字符打印出来了。但是一个地址肯定不止一个字节,也就是说超过了char应该有的大小,这时候程序会直接忽略了超出大小的部分,只读第一个字节。
如果你同时使用%p,告诉程序,你会提供一个指针,直接把这个指针指向的地址给我打印出来。把输出的地址最后两位的16进制数查ascii表,换算成字符,你会发现,刚好就是前面%c打印出的字符。

Ⅶ C语言函数及指针问题.

这个理解起来其实很简单
只要记住一点,实参和形参不在一个内存地址中就可以,改变形参不会改变实参的
但是有一个例外,就是在声明子函数是,参数带&,这表示实参形参公用一个内存地址

在调用x1函数时,i j会另外申请内存地址,那么交换了ij,但是ab所在的内存地址的内容是不会改变的

调用x2时,传递过去的是ab的内存地址,并且在子函数中,交换了ab内存地址中的内容,那么ab就交换了
这个主意两点
1,交换了ab内存地址(也就是指针)中的内容,但是你看在子函数中,指针是没有交换的,所以说传递过去的参数是没有改变,只是改变了指向的地址中的内容
2,要是在子函数中声明的c是指针,如果用c=i;i=j;j=c,那么只是交换了指针,而指针指向的内容还是没有改变,并且在主函数中,这两个参数指针还是没有改变。道理同第一个,因为实参和形参是占不同的内存地址,

Ⅷ 关于C语言指针函数的问题

char*connect(char*dst,char*src)
{
char*q,*p;
for(p=dst;*p;p++);//将p指针移动到dst数组的结束符0的位置
for(q=src;*q;q++,p++)//dst从结束符开始,src从首地址开始,一一对应传值
*p=*q;
*p=0;
returndst;
}

Ⅸ c语言指向函数的指针问题

首先,这个代码连编译的过不了
单从你主函数的x=sub(p,q,3),我也不知道你那是q还是9。
忽略编程的角度,单从题目的大意,把你的q当做是9
x = sub(p,9,3) = funa(9,3) = 9+3 = 12;
x += sub(funb,8,3),x = x+funb(8,3) = 12 + (8-3) = 17
结果是17

Ⅹ 【求助】关于C语言中指向函数的指针的问题(高手进!)

/* 一 */
#include<stdio.h>
int f2(float c)
{
printf("%f\n",c);
}

void main()
{
int (*f)(); // 错误: 函数的形参是函数类型的一部分(返回值不是) 改成int (*f)(float);就好了。
float c=5;
printf("%f\n",c);
f=f2;
f(c);
getch();
}

/* main */ //修改后:(为什么这个却可以?)
/*
#include<stdio.h>
int f2(float *c)
{
printf("%f\n",*c);
}
void main()
{
int (*f)(); // 这其实也是个错误,只不过被另一个隐式规则所掩盖,那就是形参的长度:
//指针的长度是C编译器默认的整型的长度,但float不是。
float *c,a=5;
c=&a;
printf("%f\n",*c);
f=f2;
(*f)(c); // 此处,(*f)(c) 与 f(c)语法上完全等价。不同的是 (*f)(c)暴露了你是生手。
// 楼上的两个回答也暴露了他们也是生手。不同的是,他们自以为不是。
getch();
}/* main */

楼主一定记住:
1. 函数的形参是函数类型的一部分,但返回值不是。
2.指针的类型必须完整。函数指针的类型信息包括入参的信息
3. 设f是函数指针,(*f)(c) 与 f(c)完全等价。但技术人员用后者。
原因 此时,操作符 () 与 []类似,已经解除引用。
(*f)(c) 的存在是编译器设计者的宽容。

-------------------------------------------------------------------
附件:microsoft C++ 汇编结果,供比较:
// 汇编:原型为 int (*f)();时的调用:
; 33 : //int (*f)(float);
; 34 : int (*f)();
; 35 : float c=5;

mov DWORD PTR _c$[ebp], 1084227584 ; 40a00000H

; 36 : printf("%f\n",c);

fld DWORD PTR _c$[ebp]
sub esp, 8
fstp QWORD PTR [esp]
push OFFSET FLAT:??_C@_03FBAH@?$CFf?6?$AA@ ; `string'
call _printf
add esp, 12 ; 0000000cH

; 37 : f=f2;

mov DWORD PTR _f$[ebp], OFFSET FLAT:_f2

; 38 : f(c);

fld DWORD PTR _c$[ebp]
mov esi, esp
sub esp, 8
fstp QWORD PTR [esp]
call DWORD PTR _f$[ebp]
add esp, 8
cmp esi, esp
call __chkesp

// 汇编:原型为 int (*f)(float);时的调用:

; 33 : int (*f)(float);
; 34 : //int (*f)();
; 35 : float c=5;

mov DWORD PTR _c$[ebp], 1084227584 ; 40a00000H

; 36 : printf("%f\n",c);

fld DWORD PTR _c$[ebp]
sub esp, 8
fstp QWORD PTR [esp]
push OFFSET FLAT:??_C@_03FBAH@?$CFf?6?$AA@ ; `string'
call _printf
add esp, 12 ; 0000000cH

; 37 : f=f2;

mov DWORD PTR _f$[ebp], OFFSET FLAT:_f2

; 38 : f(c);

mov esi, esp
mov eax, DWORD PTR _c$[ebp]
push eax
call DWORD PTR _f$[ebp]
add esp, 4
cmp esi, esp
call __chkesp