1、指向函数的指针
在C语言中,函数名实际上是一个指向函数的指针,所以你可以直接使用函数名add
来初始化函数指针,而不需要使用&add
。在这种情况下,add
和&add
是等价的。
这是因为在C语言中,函数名是函数的入口地址的别名。当你使用函数名时,你实际上获取的是函数的入口地址。这就是为什么你可以直接使用函数名来初始化函数指针的原因。
所以,以下两种方式都是可以的:
int (*operations[5])(int, int) = {add, substract, multiply, divide, module};
或者
int (*operations[5])(int, int) = {&add, &substract, &multiply, ÷, &module};
它们都会创建一个函数指针数组,这个数组的元素都是指向一个接受两个int
参数并返回int
的函数的指针。
2、指向字符串的指针
这两种声明方式实际上是不同的,它们创建的数组类型和内容都不同。
char *arr[] = {"add", "subtract", "multiply", "divide", "module"};
这种方式创建的是一个指针数组。数组的每个元素都是一个字符指针,指向一个C风格的字符串(以null结尾的字符数组)。因此,arr[0]
是一个指针,指向字符串"add"
。
char arr[] = {"add", "subtract", "multiply", "divide", "module"};
这种方式试图创建一个字符数组,但是这是错误的。在C语言中,不能这样声明一个字符数组。你可以声明一个单一的字符串,如char arr[] = "add";
,这会创建一个字符数组,其中包含字符'a'
, 'd'
, 'd'
, 和一个结束符'\0'
。但是你不能一次声明多个字符串。
如果你想要创建一个包含多个字符串的数组,你应该使用字符指针数组,即第一种方式。
3、指针数组
在C语言中,int *p;
和int (*ptr)[5];
都是指针的声明,但它们指向的对象类型不同。
-
int *p;
:这是一个指向整数的指针。在你的代码中,p = arr;
使得p指向数组arr的第一个元素。 -
int (*ptr)[5];
:这是一个指向整型数组(该数组具有5个元素)的指针。你可以这样理解,ptr是一个指针,它指向一个整型数组,这个数组包含5个整数。
这两者的区别在于,p
是一个可以直接指向单个整型的指针,而ptr
是一个指向整个含有5个整型元素的数组的指针。如果你试图通过ptr
访问数组中的元素,你需要先解引用ptr
得到数组,然后再使用下标访问元素。而对于p
,你可以直接通过增加指针的值来访问数组的下一个元素。
这种区别主要体现在指针的算术运算上。如果p
指向数组的一个元素,那么p+1
将会指向数组的下一个元素。但如果ptr
指向一个含有5个元素的数组,那么ptr+1
将会指向下一个5元素数组的首地址,而不是当前数组的下一个元素。
-
指针的大小:这是指存储地址所需要的字节大小。在32位系统中,指针通常是4字节,而在64位系统中,指针通常是8字节。这是因为64位系统可以寻址的内存空间比32位系统大得多,所以需要更多的字节来存储内存地址。
-
指针指向的数据的大小:这是指指针指向的具体数据所占用的字节大小。例如,一个
int
类型的数据在大多数系统中占用4字节,无论是32位系统还是64位系统。
所以,如果你说一个指针存储的地址是8字节,那么这个指针可能是在64位系统中的,但这并不意味着它指向的数据也一定是8字节或64位的。它指向的数据的大小取决于数据的类型。
4、类型定义
在C语言中,函数指针的类型是基于它所指向的函数的返回类型和参数类型。例如,int (*fp)(int, int)
是一个函数指针,它指向一个接受两个int
参数并返回int
的函数。你可以直接使用这种方式定义函数指针,而不必创建一个新的类型别名。
在你的示例中,int (*operations[5])(int, int) = {add, substract, multiply, divide, module};
就是这样的一个例子。这里,operations
是一个数组,它的元素都是函数指针,这些函数指针都指向一个接受两个int
参数并返回int
的函数。
创建函数指针类型(例如typedef int (*operation_fun)(int, int);
)主要是为了代码的可读性和便利性。如果你在代码的多个地方需要使用到同一种类型的函数指针,那么创建一个函数指针类型就可以使代码更简洁、更易于阅读和维护。但是,这并不是必须的,你完全可以选择直接使用函数指针,而不创建类型别名。
#include <stdio.h> // 假设你已经定义了这些函数 int add(int, int); int substract(int, int); int multiply(int, int); int divide(int, int); int module(int, int); // 定义函数指针类型 typedef int (*operation_fun)(int, int); int main() { char *arr[] = {"add", "substract", "multiply", "divide", "module"}; // 初始化函数指针数组 operation_fun operations[] = { &add, &substract, &multiply, ÷, &module }; int result = 0; int i; for (i = 0; i < 5; i++) { result = operations[i](10, 20); printf("%s of two number result is %d\n", arr[i], result); } return 0; }
#include <stdio.h> #define MAX 10 void swap(int *x, int *y) { int temp; temp = *x; *x = *y; *y = temp; } void fun(int *height, int *age) { int n = 10; *height = n * 10; *age = n * 2000; } int *createArray(int size) { int i; int *arr = (int *)(malloc(sizeof(int) * size)); for (i = 0; i < size; i++) { arr[i] = i * i; } return arr; } int add(int x, int y) { return x + y; } int substract(int x, int y) { return x - y; } int multiply(int x, int y) { return x * y; } int divide(int x, int y) { return x / y; } int module(int x, int y) { return x % y; } typedef int (*operation_fun)(int, int); void main() { int num = 0; int (*ptr_add)(int, int) = add; void (*ptr_swap)(int, int) = swap; int a = 100, b = 200; int sum = ptr_add(a, b); ptr_swap(&a, &b); printf("the result is %d\n", sum); printf("after swap a is %d,b is %d\n", a, b); operation_fun operations[] = { &add, &substract, &multiply, ÷, &module}; // int (*operations[])(int, int) = {add, substract, multiply, divide, module}; // int (*operations[])(int, int) = {&add, &substract, &multiply, ÷, &module}; char *arr[] = {"add", "substract", "multiply", "divide", "module"}; int result = 0; int i; for (i = 0; i < 5; i++) { result = operations[i](10, 20); printf("%s of two number result is %d\n", arr[i], result); } // int a = 100, b = 200; // printf("before swap a is %d, b is %d\n", a, b); // swap(&a, &b); // printf("after swap a is %d, b is %d\n", a, b); // int p_height; // int p_age; // int *p_arr = createArray(MAX); // int i; // fun(&p_height, &p_age); // printf("height is %d and age is %d\n", p_height, p_age); // for (i = 0; i < MAX; i++) // { // printf("%d\n", p_arr[i]); // } // int c = 30; // int *ptr1 = &c; // int **ptr2 = &ptr1; // printf("c is %d\n", c); // printf("ptr1 is %d\n", *ptr1); // printf("ptr2 is %d\n", **ptr2); }
2023/11/17 16:34:01 2023/11/17 16:38:53 重试 删除 固定 复制
2023/11/24 16:05:36 重试 删除 固定 复制
在C语言中,函数指针的类型是基于它所指向的函数的返回类型和参数类型。例如,int (*fp)(int, int)
是一个函数指针,它指向一个接受两个int
参数并返回int
的函数。你可以直接使用这种方式定义函数指针,而不必创建一个新的类型别名。
在你的示例中,int (*operations[5])(int, int) = {add, substract, multiply, divide, module};
就是这样的一个例子。这里,operations
是一个数组,它的元素都是函数指针,这些函数指针都指向一个接受两个int
参数并返回int
的函数。
创建函数指针类型(例如typedef int (*operation_fun)(int, int);
)主要是为了代码的可读性和便利性。如果你在代码的多个地方需要使用到同一种类型的函数指针,那么创建一个函数指针类型就可以使代码更简洁、更易于阅读和维护。但是,这并不是必须的,你完全可以选择直接使用函数指针,而不创建类型别名