首页 > 其他分享 >c语言中的指针用法

c语言中的指针用法

时间:2023-11-24 16:58:55浏览次数:26  
标签:语言 指向 int 用法 add 数组 函数指针 指针

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

标签:语言,指向,int,用法,add,数组,函数指针,指针
From: https://www.cnblogs.com/dogingate/p/17854112.html

相关文章

  • 镜像搬运工 skopeo简单用法
    https://blog.51cto.com/u_16099262/6928212https://blog.csdn.net/easylife206/article/details/125093122https://github.com/containers/skopeo1安装dnf-yinstallskopeo本地搭建私有仓库#安装dockerdnfinstalldocker#下载并启动一个register容器,创建本地私有......
  • 开源大模型驱动的智能编程与自然语言处理
    随着人工智能技术的不断发展,开源大模型已经成为了一个备受关注的话题。在这些开源大模型中,WizardCoder和WizardLM是两个备受瞩目的项目。本文将重点介绍这两个模型,并突出其中的重点词汇或短语。首先,让我们来了解一下WizardCoder。它是一个基于PyTorch框架的开源代码生成工具,......
  • C语言之结构体—下
    单链表示例案例1:创建并访问一个带头结点的、存储整型数据的单链表,数据从键盘输入,0为输入结束标志。#include<stdio.h>#include<stdlib.h>structlinkRec{intdata;structlinkRec*next;};intmain(){intx;structlinkRec*head,*p,*rear;head=......
  • Android新手必学:Fragment的用法
    引言Fragment是Android开发中一个重要的组件,它可以被认为是一个模块化的UI组件,用于构建灵活和可重用的界面。在Android应用程序中使用Fragment可以实现更好的UI组织、模块化开发和适配多屏幕等需求。本文将介绍Fragment的基本概念和用法,帮助Android新手开发者快速上手使用Fragment......
  • 这么多年关于SQL关键字你不知道的那些用法........
    简单聊聊,常用的sql关键字还可以这样用…来访者,你好,请叫我标题党!!!---------------------------------------------------------------------------------------------------------------.对于很多时候代码写的好与坏主要取决于sql语句6不6,话不多说上代码主要是讲解查询sql增加啊,......
  • 10_填充每个节点的下一个右侧节点指针
    填充每个节点的下一个右侧节点指针给定一个完美二叉树,其所有叶子节点都在同一层,每个父节点都有两个子节点。二叉树定义如下:structNode{intval;Node*left;Node*right;Node*next;}填充它的每个next指针,让这个指针指向其下一个右侧节点。如果找不到下一个......
  • surface pro4 鼠标指针闪烁、触摸屏不灵
    同事的平板长时间不用。出现:鼠标指标闪烁,触摸屏不灵的情况。尝试:一、更新系统问题依然出现二、调整各种设置总是依然出现三、百度到一篇可能是设备冲突禁用人机接口中的第一个“符合HID标准的触摸屏”总是解决。各文中提到的现象不完全一致,但类似。猜想可能是设备冲突引......
  • 【转载】Qt中的智能指针
    不用到处找了,附高质量博客链接Qt智能指针介绍:QSharedPointer、QWeakPointer、QScopedPointer、QPointer(附实例)-CSDN博客Qt智能指针信号槽连接问题_qtconnect智能指针_Jason~shen的博客-CSDN博客......
  • R语言集成模型:提升树boosting、随机森林、约束最小二乘法加权平均模型融合分析时间序
    原文链接:http://tecdat.cn/?p=24148原文出处:拓端数据部落公众号 最近我们被要求撰写关于集成模型的研究报告,包括一些图形和统计输出。特别是在经济学/计量经济学中,建模者不相信他们的模型能反映现实。比如:收益率曲线并不遵循三因素的Nelson-Siegel模型,股票与其相关因素之间的......
  • 在r语言中使用GAM(广义相加模型)进行电力负荷时间序列分析|附代码数据
    原文链接:http://tecdat.cn/?p=9024原文出处:拓端数据部落公众号  最近我们被要求撰写关于GAM的研究报告,包括一些图形和统计输出。用GAM进行建模时间序列我已经准备了一个文件,其中包含四个用电时间序列来进行分析。数据操作将由data.table程序包完成。将提及的智能电表数据......