c语言中的指针用法

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, &divide, &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];都是指针的声明,但它们指向的对象类型不同。

  1. int *p;:这是一个指向整数的指针。在你的代码中,p = arr;使得p指向数组arr的第一个元素。

  2. int (*ptr)[5];:这是一个指向整型数组(该数组具有5个元素)的指针。你可以这样理解,ptr是一个指针,它指向一个整型数组,这个数组包含5个整数。

这两者的区别在于,p是一个可以直接指向单个整型的指针,而ptr是一个指向整个含有5个整型元素的数组的指针。如果你试图通过ptr访问数组中的元素,你需要先解引用ptr得到数组,然后再使用下标访问元素。而对于p,你可以直接通过增加指针的值来访问数组的下一个元素。

这种区别主要体现在指针的算术运算上。如果p指向数组的一个元素,那么p+1将会指向数组的下一个元素。但如果ptr指向一个含有5个元素的数组,那么ptr+1将会指向下一个5元素数组的首地址,而不是当前数组的下一个元素。

 
在计算机中,一个指针的大小(即它存储的地址的大小)和它指向的数据的大小是两个不同的概念。
  1. 指针的大小:这是指存储地址所需要的字节大小。在32位系统中,指针通常是4字节,而在64位系统中,指针通常是8字节。这是因为64位系统可以寻址的内存空间比32位系统大得多,所以需要更多的字节来存储内存地址。

  2. 指针指向的数据的大小:这是指指针指向的具体数据所占用的字节大小。例如,一个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);)主要是为了代码的可读性和便利性。如果你在代码的多个地方需要使用到同一种类型的函数指针,那么创建一个函数指针类型就可以使代码更简洁、更易于阅读和维护。但是,这并不是必须的,你完全可以选择直接使用函数指针,而不创建类型别名。

2023/11/24 16:05:36
 
smiley
 
#include <stdio.h>// 假设你已经定义了这些函数intadd(int, int); intsubstract(int, int); intmultiply(int, int); intdivide(int, int); intmodule(int, int); // 定义函数指针类型typedefint(*operation_fun)(int, int); intmain() { char *arr[] = {"add", "substract", "multiply", "divide", "module"}; // 初始化函数指针数组 operation_fun operations[] = { &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); } return0; }
 
 
 
删除
 
固定
 
复制
 

 

#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,
        &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);
    }
    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,
        &divide,
        &module};

    // int (*operations[])(int, int) = {add, substract, multiply, divide, module};
    // int (*operations[])(int, int) = {&add, &substract, &multiply, &divide, &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
 
smiley
 
重试
 
删除
 
固定
 
复制

 

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);)主要是为了代码的可读性和便利性。如果你在代码的多个地方需要使用到同一种类型的函数指针,那么创建一个函数指针类型就可以使代码更简洁、更易于阅读和维护。但是,这并不是必须的,你完全可以选择直接使用函数指针,而不创建类型别名

posted on 2023-11-24 16:43  风中狂笑  阅读(7)  评论(0编辑  收藏  举报

导航