函数参数中的 int * 与 int [] 与 int (*)[] 。我应该使用哪一个?

2024-02-17

在 C 编程语言中,有许多不同的方法来声明将数组作为通过指针传递的参数的函数的参数。

我准备了一个例子来说明我的意思。它是一个实现std::accumulateC++ 中的函数。它是一个将数组中所有元素相加并返回结果的函数。

我可以这样写:

int accumulate(int n, int *array)
{
    int i;
    int sum = 0;
    for (i = 0; i < n; ++i) {
        sum += array[i];
    }
    return sum;
}

这也可以写成this(这意味着完全相同的事情):

int accumulate(int n, int array[])
{
    int i;
    int sum = 0;
    for (i = 0; i < n; ++i) {
        sum += array[i];
    }
    return sum;
}

我也可以这样写:

int accumulate(int n, int (*array)[])
{
    int i;
    int sum = 0;
    for (i = 0; i < n; ++i) {
        sum += (*array)[i];
    }
    return sum;
}

所有这些选项都非常相似,并生成相同的可执行代码,但它们有细微的差别,即调用者传递参数的方式。

前两个版本的调用方式如下:

int main(void)
{
    int a[] = {3, 4, 2, 4, 6, 1, -40, 23, 35};
    printf("%d\n", accumulate(ARRAY_LENGTH(a), a));
    return 0;
}

这是第三个版本的调用方式:

int main(void)
{
    int a[] = {3, 4, 2, 4, 6, 1, -40, 23, 35};
    printf("%d\n", accumulate(ARRAY_LENGTH(a), &a));
    return 0;
}

请注意,第三个选项要求用户明确指定a with &a。前两个选项不需要这样做,因为数组会隐式转换为指向 C 中相同类型的指针。

我一直更喜欢第三种方法。

这就是为什么:

  • 它与其他类型通过指针传递的方式更加一致。

    int draw_point(struct point *p);
    
    int main()
    {
        struct point p = {3, 4};
        draw_point(&p); // Here is the 'address of' operator required.
    }
    
  • 它使得使用宏成为可能ARRAY_LENGTH获取数组中元素的数量。

    #include <stdio.h>
    #define ARRAY_LENGTH(A) (sizeof(A) / sizeof(A[0]))
    
    void this_works(int (*array)[10])
    {
        /* This works! */
        printf("%d\n", ARRAY_LENGTH(*array));
    }
    
    void this_is_invalid_and_dangerous(int array[10])
    {
        /* This does NOT work because `array` is actually a pointer. */
        printf("%d\n", ARRAY_LENGTH(array));
    }
    

我看到的唯一优势int array[] (and int *array) over int (*array)[]你可以写array[X]代替(*array)[X]当你想获取索引时。

但因为我不是专业人士,我会问你更喜欢哪个版本。

什么时候用什么?选择其中一种而不是另一种的原因是什么?

我大部分都用过int (*array)[N]但我发现其他两种方法也很常见。


当用作函数参数时,int array[] and int *array是一样的。您可以使用其中任何一个。这是品味问题。int (*array)[]很乏味并且没有广泛使用。

int (*array)[n]当二维数组传递给函数时使用最广泛。在这种情况下,您可以访问数组的元素:array[i][j].

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

函数参数中的 int * 与 int [] 与 int (*)[] 。我应该使用哪一个? 的相关文章

  • 确保 StreamReader 不会挂起等待数据

    下面的代码读取从 tcp 客户端流读取的所有内容 并且在下一次迭代中它将仅位于 Read 上 我假设正在等待数据 我如何确保它不会在没有任何内容可供读取时返回 我是否必须设置低超时 并在失败时响应异常 或者有更好的办法吗 TcpClient
  • 复制 std::function 的成本有多高?

    While std function是可移动的 但在某些情况下不可能或不方便 复制它会受到重大处罚吗 它是否可能取决于捕获变量的大小 如果它是使用 lambda 表达式创建的 它依赖于实现吗 std function通常被实现为值语义 小缓
  • 使用 LINQ2SQL 在 ASP.NET MVC 中的各种模型存储库之间共享数据上下文

    我的应用程序中有 2 个存储库 每个存储库都有自己的数据上下文对象 最终结果是我尝试将从一个存储库检索到的对象附加到从另一个存储库检索到的对象 这会导致异常 Use 构造函数注入将 DataContext 注入每个存储库 public cl
  • 单个对象的 Monogame XNA 变换矩阵?

    我读过一些解释 XNA Monogame 变换矩阵的教程 问题是这些矩阵应用于 SpriteBatch Begin matrix 这意味着所有 Draw 代码都将被转换 如何将变换矩阵应用于单个可绘制对象 就我而言 我想转换滚动背景 使其自
  • java.io.Serialized 在 C/C++ 中的等价物是什么?

    C C 的等价物是什么java io Serialized https docs oracle com javase 7 docs api java io Serializable html 有对序列化库的引用 用 C 序列化数据结构 ht
  • 如何使用 LINQ2SQL 连接两个不同上下文的表?

    我的应用程序中有 2 个数据上下文 不同的数据库 并且需要能够通过上下文 B 中的表的右连接来查询上下文 A 中的表 我该如何在 LINQ2SQL 中执行此操作 Why 我们正在使用 SaaS 产品来跟踪我们的时间 项目等 并希望向该产品发
  • 我可以使用 moq Mock 来模拟类而不是接口吗?

    正在经历https github com Moq moq4 wiki Quickstart https github com Moq moq4 wiki Quickstart 我看到它 Mock 一个接口 我的遗留代码中有一个没有接口的类
  • 如何在 32 位或 64 位配置中以编程方式运行任何 CPU .NET 可执行文件?

    我有一个可在 32 位和 64 位处理器上运行的 C 应用程序 我试图枚举给定系统上所有进程的模块 当尝试从 64 位应用程序枚举 32 位进程模块时 这会出现问题 Windows 或 NET 禁止它 我认为如果我可以从应用程序内部重新启动
  • 使用自定义堆的类似 malloc 的函数

    如果我希望使用自定义预分配堆构造类似 malloc 的功能 那么 C 中最好的方法是什么 我的具体问题是 我有一个可映射 类似内存 的设备 已将其放入我的地址空间中 但我需要获得一种更灵活的方式来使用该内存来存储将随着时间的推移分配和释放的
  • Azure 辅助角色“请求输入之一超出范围”的内部异常。

    我在辅助角色中调用 CloudTableClient CreateTableIfNotExist 方法 但收到一个异常 其中包含 请求输入之一超出范围 的内部异常 我做了一些研究 发现这是由于将表命名为非法表名引起的 但是 我尝试为我的表命
  • 如何禁用 fread() 中的缓冲?

    我正在使用 fread 和 fwrite 读取和写入套接字 我相信这些函数用于缓冲输入和输出 有什么方法可以在仍然使用这些功能的同时禁用缓冲吗 Edit 我正在构建一个远程桌面应用程序 远程客户端似乎 落后于服务器 我不知道可能是什么原因
  • “接口”类似于 boost::bind 的语义

    我希望能够将 Java 的接口语义与 C 结合起来 起初 我用过boost signal为给定事件回调显式注册的成员函数 这非常有效 但后来我发现一些函数回调池是相关的 因此将它们抽象出来并立即注册所有实例的相关回调是有意义的 但我了解到的
  • 如何设置 log4net 每天将我的文件记录到不同的文件夹中?

    我想将每天的所有日志保存在名为 YYYYMMdd 的文件夹中 log4net 应该根据系统日期时间处理创建新文件夹 我如何设置它 我想将一天中的所有日志保存到 n 个 1MB 的文件中 我不想重写旧文件 但想真正拥有一天中的所有日志 我该如
  • 如何在非控制台应用程序中查看 cout 输出?

    输出到调试窗口似乎相当繁琐 我在哪里可以找到cout如果我正在编写非控制台信息 则输出 Like double i a b cout lt lt b lt lt endl I want to check out whether b is z
  • C++ 函数重载类似转换

    我收到一个错误 指出两个重载具有相似的转换 我尝试了太多的事情 但没有任何帮助 这是那段代码 CString GetInput int numberOfInput BOOL clearBuffer FALSE UINT timeout IN
  • 调用堆栈中的“外部代码”是什么意思?

    我在 Visual Studio 中调用一个方法 并尝试通过检查调用堆栈来调试它 其中一些行标记为 外部代码 这到底是什么意思 方法来自 dll已被处决 外部代码 意味着该dll没有可用的调试信息 你能做的就是在Call Stack窗口中单
  • 如果没有抽象成员,基类是否应该标记为抽象?

    如果一个类没有抽象成员 可以将其标记为抽象吗 即使没有实际理由直接实例化它 除了单元测试 是的 将不应该实例化的基类显式标记为抽象是合理且有益的 即使在没有抽象方法的情况下也是如此 它强制执行通用准则来使非叶类抽象 它阻止其他程序员创建该类
  • WebSocket安全连接自签名证书

    目标是一个与用户电脑上安装的 C 应用程序交换信息的 Web 应用程序 客户端应用程序是 websocket 服务器 浏览器是 websocket 客户端 最后 用户浏览器中的 websocket 客户端通过 Angular 持久创建 并且
  • 对具有混合类型值的数组进行数字排序

    我有一个像这样的混合数组 fruits array lemon Lemon 20 banana apple 121 40 50 然后申请sort 其功能如下 sort fruits SORT NUMERIC foreach fruits a
  • 当从finally中抛出异常时,Catch块不会被评估

    出现这个问题的原因是之前在 NET 4 0 中运行的代码在 NET 4 5 中因未处理的异常而失败 部分原因是 try finallys 如果您想了解详细信息 请阅读更多内容微软连接 https connect microsoft com

随机推荐

  • 使用 JAXB 从未编组的 java 对象中获取 xml 元素名称

    我有田地带注释的 with XmlElement name xxx 在我的 Java 模型中 有没有办法以编程方式获取 xml 元素名称 假设我们有带注释的实体 XmlRootElement public class Product Str
  • PrimaryContext 和 UserPrincipal 如何知道密码何时过期?

    我有一个UserPrincipal具有很多属性的对象 但我找不到密码过期日期的属性 如何才能做到这一点 这是我能想到的最简单的方法 using System DirectoryServices using System DirectoryS
  • R mlr3 创建TaskregrST 重复行?

    我有一个名为 tab mlr 的数据框 其中包含 788 行中约 19 个特征的坐标 str tab mlr 该天体有 21 个变量的 788 个观测值 其中 2 个变量为纬度和经度 我创建一个像这样的 sf 对象 data mlr lt
  • Inno Setup:选择组件的功能

    我有一个小问题 我需要当您选择一个或两个组件时显示一个页面 但其他的并不是只用单一的组件似乎就有效果 我留下了我正在工作的代码 Setup AppName My Program AppVerName My Program v 1 2 Def
  • Javascript + HTML5 本地存储 [关闭]

    Closed 此问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 所以我正在寻找一个关于 localstorage 的好的速成课程 并用 Javascript 与之交互
  • jQuery - :not() 中的多个选择器?

    我似乎无法进行以下工作 input not type radio type checkbox live click function alert You haven t clicked a radio or checkbox 尝试了几种不同
  • 如何使用moment js和angularjs获取子午线(上午/下午)

    我有一个关于 Moments js 库的问题 我有一个 AngularJS 中的应用程序 其中有六个选择元素 用于年 月 日 小时 分钟和上午 下午格式 我使用以下格式 moment 来构建 m format 日期 YYYY MM DD h
  • 使用 UpdateChildValues 从 Firebase 中删除

    我正在尝试同时从 Firebase 数据库中的多个位置删除数据 The Firebase 文档 https firebase google com docs database ios save data state 删除数据的最简单方法是在
  • 如何设置 $docroot 来为我提供我想要的路径

    我该如何定义 docroot路径 这样我就可以输入我自己的路径 我有代码 docroot getenv DOCUMENT ROOT 当我将它与我的 index php 结合使用时 索引 php docroot getenv DOCUMENT
  • 在 protobuf 中使用 int32 的原因

    在 gpb proto2 标量类型的描述中 https developers google com protocol buffers docs proto scalar https developers google com protoco
  • 以编程方式将谷歌设置为主屏幕自定义启动器中的搜索栏

    我正在创建 我自己的启动器 In that case I want to put我的主屏幕中的快速搜索栏 即 Google now 启动器 我怎样才能做到这一点 我已经浏览了多个线程但没有找到任何相关答案 我不想展示widget picke
  • 等待 TaskEx.Delay

    我正在使用 HttpListener 和 Async CTP class HttpServer IDisposable HttpListener listener CancellationTokenSource cts public voi
  • 请求沙盒测试者用户 ID 的 Apple 验证电子邮件

    我在获取我在 iTunesConnect 中创建的用于购买非消耗性产品的测试用户沙箱 ID 时遇到问题 创建 ID 后我等了一天才尝试使用它们 首先 我根据设备上的 Settings iTunes App Store 确保没有 ID 登录
  • 屏幕更改后的默认 UIAccessibilityElement

    有什么方法可以决定哪个元素首先获得焦点 我尝试在以下方法中使用第二个参数 UIAccessibilityPostNotification UIAccessibilityLayoutChangedNotification element 但没
  • PHPUnit:如何模拟今天的日期而不将其作为参数传递?

    我正在我的班级上测试一种进行日期检查的方法 问题是该方法取决于今天的日期 每天都在变化 这使得测试变得困难 我如何模拟今天的日期 以便我的测试明天仍能通过 我对 PHP 一无所知 但在 Java 和 C 中 我会传递一些描述的 时钟 不是今
  • 如何将 CSV 文件的表值转换为数组?

    我的价值低于我的 CSV 文件的第一列 table border 1 tr th align left First Name th th align left Gender th th align left Nationality th t
  • 这里使用哪个 XML 解析器?

    我正在接收一个 XML 文件作为输入 其大小可能从几 KB 到更多 我通过网络获取该文件 我需要根据我的使用提取少量节点 因此大部分文档对我来说毫无用处 我没有记忆偏好 我只需要速度 考虑到这一切 我得出的结论是 这里不使用 DOM 由于
  • 从 Numpy 数组中的元素创建新的 Numpy 数组

    这题好像想不通对 numpy 非常陌生 我有一个 numpy 形状数组 200 1 1000 1000 对应于 图像数量 通道 x of image y of image 所以我有 200 个图像 每个通道有 1000x1000 像素 我想
  • Java 的 G1 垃圾收集器 (G1GC) 中的类卸载

    在Java 6中我们曾经使用下面的GC配置来防止Perm GenOutOfMemoryException多次重新部署我们的应用程序后 XX UseConcMarkSweepGC XX CMSClassUnloadingEnabled 我们正
  • 函数参数中的 int * 与 int [] 与 int (*)[] 。我应该使用哪一个?

    在 C 编程语言中 有许多不同的方法来声明将数组作为通过指针传递的参数的函数的参数 我准备了一个例子来说明我的意思 它是一个实现std accumulateC 中的函数 它是一个将数组中所有元素相加并返回结果的函数 我可以这样写 int a