函数参数中的 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 (*)[] 。我应该使用哪一个? 的相关文章

  • SSH 主机密钥指纹与模式 C# WinSCP 不匹配

    我尝试通过 WinSCP 使用 C 连接到 FTPS 服务器 但收到此错误 SSH 主机密钥指纹 与模式不匹配 经过大量研究 我相信这与密钥的长度有关 当使用 服务器和协议信息 下的界面进行连接时 我从 WinSCP 获得的密钥是xx xx
  • 为什么 POSIX 允许在只读模式下超出现有文件结尾 (fseek) 进行搜索

    为什么寻找文件结尾很有用 为什么 POSIX 让我们像示例中那样在以只读方式打开的文件中进行查找 c http en cppreference com w c io fseek http en cppreference com w c io
  • 使用 Google Analytics API 在 C# 中显示信息

    我一整天都在寻找一个好的解决方案 但谷歌发展得太快了 我找不到有效的解决方案 我想做的是 我有一个 Web 应用程序 它有一个管理部分 用户需要登录才能查看信息 在本节中 我想显示来自 GA 的一些数据 例如某些特定网址的综合浏览量 因为我
  • A* 之间的差异 pA = 新 A;和 A* pA = 新 A();

    在 C 中 以下两个动态对象创建之间的确切区别是什么 A pA new A A pA new A 我做了一些测试 但似乎在这两种情况下 都调用了默认构造函数 并且仅调用了它 我正在寻找性能方面的任何差异 Thanks If A是 POD 类
  • 使用向量的 merge_sort 在少于 9 个输入的情况下效果很好

    不知何故 我使用向量实现了合并排序 问题是 它可以在少于 9 个输入的情况下正常工作 但在有 9 个或更多输入的情况下 它会执行一些我不明白的操作 如下所示 Input 5 4 3 2 1 6 5 4 3 2 1 9 8 7 6 5 4 3
  • SSRS将参数传递给子报表

    我有 2 个表 它们都有 countyID 列 我有一个主报告 它根据如下查询显示报告 SELECT countyID name address state FROM TableA 我在 TableA 上设置了一个参数 您可以在其中选择名称
  • Windows 窗体不会在调试模式下显示

    我最近升级到 VS 2012 我有一组在 VS 2010 中编码的 UI 测试 我试图在 VS 2012 中启动它们 我有一个 Windows 窗体 在开始时显示使用 AssemblyInitialize 属性运行测试 我使用此表单允许用户
  • 如何在 Team Foundation 上强制发表有意义的签入评论?

    我有一个开发团队有一个坏习惯 他们写道poor签入评论 当我们必须在团队基础上查看文件的历史记录时 这使得它成为一场噩梦 我已经启用了变更集评论政策 这样他们甚至可以在签到时留下评论 否则他们不会 我们就团队的工作质量进行了一些讨论 他们很
  • 我的 strlcpy 版本

    海湾合作委员会 4 4 4 c89 我的程序做了很多字符串处理 我不想使用 strncpy 因为它不会终止 我不能使用 strlcpy 因为它不可移植 只是几个问题 我怎样才能让我的函数正常运行 以确保它完全安全稳定 单元测试 这对于生产来
  • .NET 选项将视频文件流式传输为网络摄像头图像

    我有兴趣开发一个应用程序 它允许我从 xml 构建视频列表 包含视频标题 持续时间等 并将该列表作为我的网络摄像头流播放 这意味着 如果我要访问 ustream tv 或在实时通讯软件上激活我的网络摄像头 我的视频播放列表将注册为我的活动网
  • 用 C 实现 Unix shell:检查文件是否可执行

    我正在努力用 C 语言实现 Unix shell 目前正在处理相对路径的问题 特别是在输入命令时 现在 我每次都必须输入可执行文件的完整路径 而我宁愿简单地输入 ls 或 cat 我已经设法获取 PATH 环境变量 我的想法是在 字符处拆分
  • 在 Javascript 中创建数组

    我对 javascript 不太熟悉 并且在用 javascript 制作 2d 或者也许我可能需要 3d 数组时遇到了一些麻烦 我目前需要收集 2 条信息 一个 ID 和一个值 因此我创建了以下内容 var myArray var id
  • AccessViolationException 未处理

    我正在尝试使用史蒂夫 桑德森的博客文章 http blog stevensanderson com 2010 01 28 editing a variable length list aspnet mvc 2 style 为了在我的 ASP
  • 检查 url 是否指向文件或页面

    我们需要以下内容 如果文件确实是文件 则从 URL 下载该文件 否则 如果它是一个页面 则什么也不做 举个简单的例子 我有以下命令来下载文件 My Computer Network DownloadFile http www wired c
  • 将日期参数传递给对 MVC 操作的 ajax 调用的安全方法

    我有一个 MVC 操作 它的参数之一是DateTime如果我通过 17 07 2012 它会抛出一个异常 指出参数为空但不能有空值 但如果我通过01 07 2012它被解析为Jan 07 2012 我将日期传递给 ajax 调用DD MM
  • EPPlus Excel 更改单元格颜色

    我正在尝试将给定单元格的颜色设置为另一个单元格的颜色 该单元格已在模板中着色 但worksheet Cells row col Style Fill BackgroundColor似乎没有get财产 是否可以做到这一点 或者我是否必须在互联
  • 将一维数组转换为二维数组[重复]

    这个问题在这里已经有答案了 我正在开发一个程序 我必须将文本文件中的值读入一维数组 我已经成功获取该一维数组中的数字 m1 1 2 3 4 5 6 7 8 9 但我希望数组是 m1 1 2 3 4 5 6 7 8 9 您可以使用此代码 co
  • 如何在 C# 中播放在线资源中的 .mp3 文件?

    我的问题与此非常相似question https stackoverflow com questions 7556672 mp3 play from stream on c sharp 我有音乐网址 网址如http site com aud
  • 更改显示的 DPI 缩放大小使 Qt 应用程序的字体大小渲染得更大

    我使用 Qt 创建了一些 GUI 应用程序 我的 GUI 应用程序包含按钮和单选按钮等控件 当我运行应用程序时 按钮内的按钮和字体看起来正常 当我将显示器的 DPI 缩放大小从 100 更改为 150 或 200 时 无论分辨率如何 控件的
  • 不同类型的指针可以互相分配吗?

    考虑到 T1 p1 T2 p2 我们可以将 p1 分配给 p2 或反之亦然吗 如果是这样 是否可以不使用强制转换来完成 或者我们必须使用强制转换 首先 让我们考虑不进行强制转换的分配 C 2018 6 5 16 1 1 列出了简单赋值的约束

随机推荐

  • 使用 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