为了账号安全,请及时绑定邮箱和手机立即绑定

数组类型-分配/用作功能参数的规则

数组类型-分配/用作功能参数的规则

C
呼如林 2019-11-02 14:16:04
当我需要将数组传递给函数时,该函数的以下所有声明似乎都可以使用void f(int arr[])  void f(int arr[4]) // is this one correct?为了这:int a[]={1,2,3,4};f(a);但是当我将一个数组分配给另一个数组时,它失败了int a[]={1,2,3,4};int b[4] = a; // error: array must be initialized with a brace-enclosed initializer那么为什么将数组作为函数的参数传递却可以,但是在简单赋值的rhs上使用却是错误的呢?
查看完整描述

3 回答

?
桃花长相依

TA贡献1860条经验 获得超8个赞

为了理解差异,我们需要了解两种不同的情况。


在值上下文中,type数组的名称T等效于type 的指针T,并且等于指向数组第一个元素的指针。

在对象上下文中,类型数组的名称T不简化为指针。

什么是对象上下文?


在中a = b;,a是在对象上下文中。当您获取变量的地址时,将在对象上下文中使用它。最后,当sizeof在变量上使用运算符时,将在对象上下文中使用它。在所有其他情况下,在值上下文中使用变量。


现在我们有了这些知识,当我们这样做时:


void f(int arr[4]);

它正好相当于


void f(int *arr);

如您所知,我们可以从函数声明中忽略大小(上面为4)。这意味着您无法知道传递给的“数组”的大小f()。稍后,当您这样做时:


int a[]={1,2,3,4};

f(a);

在函数调用中,名称a位于值上下文中,因此将其简化为的指针int。这很好,因为f需要指向的指针int,所以函数定义并使用match。传递给的f()是指向a(&a[0])第一个元素的指针。


如果是


int a[]={1,2,3,4};

int b[4] = a;

该名称b在对象上下文中使用,并且不会简化为指针。(顺便说一下,a这里是在值上下文中,并简化为指针。)


现在,int b[4];分配4 ints的存储时间并为其命名b。 a还被分配了类似的存储空间。因此,实际上,上述分配表示“我要使存储位置与先前的位置相同”。这没有道理。


如果要将内容复制a到中b,则可以执行以下操作:


#include <string.h>

int b[4];

memcpy(b, a, sizeof b);

或者,如果你想要一个指针b是指向a:


int *b = a;

在这里,它a是在value上下文中,并简化为的指针int,因此我们可以分配a给int *。


最后,在初始化数组时,您可以为其分配显式值:


int a[] = {1, 2, 3, 4};

在这里,a有4个元素,分别初始化为1、2、3和4。您也可以这样做:


int a[4] = {1, 2, 3, 4};

如果列表中的元素数少于数组中的元素数,则其余值将取为0:


int a[4] = {1, 2};

将a[2]和设置a[3]为0。


查看完整回答
反对 回复 2019-11-02
?
慕姐4208626

TA贡献1852条经验 获得超7个赞

void f(int arr[]);

void f(int arr[4]);

语法具有误导性。它们都与此相同:


void f(int *arr);

即,您正在传递一个指向数组开头的指针。您不复制阵列。


查看完整回答
反对 回复 2019-11-02
  • 3 回答
  • 0 关注
  • 388 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信