如何将条件作为参数传递给C中的函数?
我创建了一个函数指针数组来交换两个变量。 指向这些函数的指针,即:swap1、swap2。swap3和swap4。 swap2使用作为参数传递的指针进行交换。 但是在声明函数指针时,只有int和int作为参数传递。编译后,这会导致许多警告。 因此,我们是否有更好的方法传递参数,在函数调用本身中放入条件。 代码如下所示如何将条件作为参数传递给C中的函数?,c,function,pointers,function-pointers,function-parameter,C,Function,Pointers,Function Pointers,Function Parameter,我创建了一个函数指针数组来交换两个变量。 指向这些函数的指针,即:swap1、swap2。swap3和swap4。 swap2使用作为参数传递的指针进行交换。 但是在声明函数指针时,只有int和int作为参数传递。编译后,这会导致许多警告。 因此,我们是否有更好的方法传递参数,在函数调用本身中放入条件。 代码如下所示 #include <stdio.h> int swap1(int ,int ); int swap2(int* ,int* ); int sw
#include <stdio.h>
int swap1(int ,int );
int swap2(int* ,int* );
int swap3(int ,int );
int swap4(int, int);
int swap1(int a,int b)
{
int temp=a;
a=b;
b=temp;
printf("swapped with 3rd variable :%d, %d\n", a,b);
}
int swap2(int *a,int *b)
{
int temp = *a;
*a = *b;
*b = temp;
printf("swapped with pointer :%d, %d\n", *a,*b);
}
int swap3(int a,int b)
{
a+=b;
b=a-b;
a-=b;
printf("swapped with 2 variable :%d, %d\n", a,b);
}
int swap4(int a,int b)
{
a=a^b;
b=a^b;
a=a^b;
printf("swapped with bitwise operation :%d, %d\n", a,b);
}
int main()
{
int ch;
int a=3;
int b=4;
printf("enter the option from 0 to 3\n");
scanf("%d",&ch);
int (*swap[4])(int, int) ={swap1,swap2,swap3,swap4};// function pointer
/*can we pass something like int(*swap[4]( condition statement for 'pointer to variable' or 'variable')*/
if (ch==1)// at '1' location, swap2 is called.
{
(*swap[ch])(&a,&b);//passing the addresses
}
else
{
(*swap[ch])(a,b);
}
return 0;
}
嗯,是的。您的代码中存在许多问题,但我将重点介绍与您提供的警告相关的问题。将
swap
声明为四个指针的数组,指向接受两个int
参数并返回int
的函数:
函数swap2()
不是这样的函数,因此指向它的指针的类型不适合作为数组的成员。编译器可能会完全拒绝这些代码,而不仅仅是发出警告,从而对您有更好的帮助
不管怎样,在编译器的警告之上,在数组中输入了指向swap2()
的指针后,您认为程序如何通过指针正确调用该函数?指针的类型要求函数参数为int
s;您的编译器再次执行可疑的服务,只接受带有警告的代码,而不是拒绝它
由于实际上提供的参数是正确的类型,因此它实际上可能在系统上以及在int
和int*
表示兼容的条件下工作。然而,这并不是编写此类代码的借口
由于指针和int
s在默认参数提升下保持不变,一种替代方法是从数组声明中省略原型:
int (*swap[4])() = {swap1,swap2,swap3,swap4};
也就是说,每个指针指向一个函数,该函数返回int
,并接受固定数量但未指定类型的参数。在调用时,实际参数将服从默认参数提升,但在本例中这不是问题。此选项确实会阻止编译器对参数执行类型检查,但事实上,否则无法正确执行此操作
您的编译器可能仍然会对此发出警告,或者可能会使用正确的选项发出警告,但结果代码仍然符合并执行正确的操作,即它使用正确的参数调用指向函数。是的。您的代码中存在许多问题,但我将重点介绍与您提供的警告相关的问题。将
swap
声明为四个指针的数组,指向接受两个int
参数并返回int
的函数:
函数swap2()
不是这样的函数,因此指向它的指针的类型不适合作为数组的成员。编译器可能会完全拒绝这些代码,而不仅仅是发出警告,从而对您有更好的帮助
不管怎样,在编译器的警告之上,在数组中输入了指向swap2()
的指针后,您认为程序如何通过指针正确调用该函数?指针的类型要求函数参数为int
s;您的编译器再次执行可疑的服务,只接受带有警告的代码,而不是拒绝它
由于实际上提供的参数是正确的类型,因此它实际上可能在系统上以及在int
和int*
表示兼容的条件下工作。然而,这并不是编写此类代码的借口
由于指针和int
s在默认参数提升下保持不变,一种替代方法是从数组声明中省略原型:
int (*swap[4])() = {swap1,swap2,swap3,swap4};
也就是说,每个指针指向一个函数,该函数返回int
,并接受固定数量但未指定类型的参数。在调用时,实际参数将服从默认参数提升,但在本例中这不是问题。此选项确实会阻止编译器对参数执行类型检查,但事实上,否则无法正确执行此操作
您的编译器可能仍然会对此发出警告,或者可能会使用正确的选项诱导编译器发出警告,但是生成的代码仍然符合并执行正确的操作,从某种意义上说,它调用具有正确参数的指向函数。首先处理警告:声明一个接受
int
参数的函数数组。这意味着swap2
与放置它的数组的元素类型不兼容。这将生成一个诊断
此外,当您调用数组中的一个函数时,相同的数组声明会告诉编译器参数必须是int
s,而不是指向int
的指针。这里有两个诊断,每个参数一个
要解决上述问题,您的函数需要具有与数组元素类型兼容的原型。它应该是int
还是int*
?这就引出了另一个问题
C函数参数总是按值传递。这意味着参数将从变量复制到堆栈上(或复制到参数寄存器中,具体取决于调用约定和参数计数-为了简单起见,在本文的其余部分,我将假设参数放置在堆栈上)。如果它是一个文本,则将文本值放在堆栈上。如果被调用方更改了堆栈上的值,则在函数返回后,调用方不会尝试将新值放回变量中。这些论点被简单地抛弃了
因此,在C语言中,如果你想做等价的引用调用,你必须
int (*swap[4])() = {swap1,swap2,swap3,swap4};
int (*swap[4])(int*, int*) = {swap1, swap2, swap3, swap4};
// main.c
#include <stdio.h>
void swap1(int* aPtr, int* bPtr) {
printf("swap1 has been called.\n");
int tmp = *aPtr;
*aPtr = *bPtr;
*bPtr = tmp;
}
void swap2(int* aPtr, int* bPtr) {
printf("swap2 has been called.\n");
*aPtr += *bPtr;
*bPtr = *aPtr - *bPtr;
*aPtr -= *bPtr;
}
int main() {
int a = 1, b = 2;
printf("a is now %d, and b is %d\n\n", a, b);
// Declare and set the function table
void (*swapTbl[2])(int*, int*) = {&swap1, &swap2};
// Ask for a choice
int choice;
printf("Which swap algorithm to use? (specify '1' or '2')\n>>> ");
scanf("%d", &choice);
printf("\n");
// Swap a and b using the right function
swapTbl[choice - 1](&a, &b);
// Print the values of a and b
printf("a is now %d, and b is %d\n\n", a, b);
return 0;
}
$ gcc main.c && ./a.out
a is now 1, and b is 2
Which swap algorithm to use? (specify '1' or '2')
>>> 2
swap2 has been called.
a is now 2, and b is 1