Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/63.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Arrays 连续数组_Arrays_C - Fatal编程技术网

Arrays 连续数组

Arrays 连续数组,arrays,c,Arrays,C,我对C18标准中的一句话很好奇: 当且仅当两个指针都是空指针时,两个指针比较相等 是指向同一对象的指针(包括指向对象的指针和 子对象(位于其开头)或函数,两者都是指向一个的指针 超过同一数组对象的最后一个元素,或其中一个是指向 一个超过一个数组对象的末尾,另一个是指向 立即发生在上的不同数组对象的开始 跟随地址空间中的第一个数组对象。§6.5.9.6 为什么数组后面的对象必须是另一个数组?不能简单地成为与数组基类型相同类型的对象(例如紧跟在int[]之后的int) 难怪我尝试了以下代码: #in

我对C18标准中的一句话很好奇:

当且仅当两个指针都是空指针时,两个指针比较相等 是指向同一对象的指针(包括指向对象的指针和 子对象(位于其开头)或函数,两者都是指向一个的指针 超过同一数组对象的最后一个元素,或其中一个是指向 一个超过一个数组对象的末尾,另一个是指向 立即发生在上的不同数组对象的开始 跟随地址空间中的第一个数组对象。§6.5.9.6

为什么数组后面的对象必须是另一个数组?不能简单地成为与数组基类型相同类型的对象(例如紧跟在
int[]
之后的
int

难怪我尝试了以下代码:

#include <stdio.h>

struct test { int arr[10]; int i; };

int main() {
    struct test t;
    int *p, *q;
    p = t.arr + 10;
    q = &t.i;
    if (p == q)
        printf("Equal pointers.");
    return 0;
}
#包括
结构测试{intarr[10];inti;};
int main(){
结构测试t;
int*p,*q;
p=t.arr+10;
q=&t.i;
如果(p==q)
printf(“等指针”);
返回0;
}

它会产生相等的指针。难道这种行为根本不能保证,只是实现定义的巧合吗?

标准中的关键词是“或”

当且仅当两个指针都是空指针时,两个指针比较相等 是指向同一对象的指针(包括指向对象的指针和 子对象(位于其开头)或函数,两者都是指向一个的指针 超过同一数组对象的最后一个元素,一个是指向 一个超过一个数组对象的末尾,另一个是指向 紧接着的另一个数组对象的开始 地址空间中的第一个数组对象

如果在地址空间中有一个数组后跟一个结构,编译器将布局该数组,然后将该结构的开头与字边界对齐,而不是紧跟在该数组之后。在这种情况下,指针不能保证相等。在大多数体系结构中,它们是不相等的

之所以将数组称为约束,是因为数组可以包含任何内容:std::byte、char、int、long、double等,指针解引用操作是否成功取决于指向和访问的内容。如果您将指针指向内存中的特定字节,并将其作为长字节取消引用,如果它未在单词边界上对齐,则会出现分段错误。如果将其作为char或std::byte解除引用,则将成功。指针不关心这一点,但取消引用它的调用方必须关心这一点。请记住,在取消引用之前,指针可以转换为不同的类型

这就是标准特别包括阵列的原因


正如其他人指出的,标准中指针相等条件的第一部分有助于实现迭代器、数组访问、迭代器::begin()、迭代器::end()等。

首先,在此处指定数组并不排除/禁止单个对象。内存中的单个对象与大小为1的数组无法区分

编辑:阅读标准中的引用,该引用在引用指针时明确说明了这一点)

其次,该标准还试图澄清您引用的陈述,以下脚注指出了适用该规则的情况:

两个对象可以在内存中相邻,因为它们是相邻的 较大阵列的元素或结构的相邻构件 它们之间的填充,或者因为实现选择了放置 他们是这样的,即使他们是无关的

综上所述,标准在这里试图说明的是,一般来说,指向不同对象的两个指针不应该相等。但是,由于将一个指针指向内存中的数组对象之外是合法的,因此,如果该位置恰好有一个不同的(数组)对象,则该指针与指向相邻对象的指针进行比较仍然是合法的。现在,由于对齐选择和填充,该位置可能有有效对象,也可能没有有效对象,但如果有,这些指针可以进行相等比较

在您的示例中,如果我将数组更改为char,指针可能会比较不相等,因为编译器会选择将int与4字节对齐(在大多数32位或64位平台上),从而引入填充。根据标准,这种行为仍然是合法的

#include <stdio.h>

struct test { char arr[10]; int i; };

int main() {
    struct test t;
    int *p, *q;
    p = (int*)(t.arr + 10);
    q = &t.i;
    if(p == q)
      printf("Equal pointers.");
    else
      printf("Unequal pointers.");
    return 0;
}
#包括
结构测试{char arr[10];int i;};
int main(){
结构测试t;
int*p,*q;
p=(int*)(t.arr+10);
q=&t.i;
如果(p==q)
printf(“等指针”);
其他的
printf(“不等指针”);
返回0;
}
OP:为什么数组后面的对象必须是另一个数组

事实并非如此。“…不同数组的开始…”是一种简化。下一个规范是:

对于这些运算符,指向不是数组元素的对象的指针的行为与指向长度为1且对象类型为其元素类型的数组的第一个元素的指针的行为相同。C17dr§6.5.9 7


OP:不能只是一个类型与数组基类型相同的对象(比如紧跟在
int[]
之后的
int


是的。

我认为在这里指定数组并不排除它是单个对象的可能性。单个int也可以被视为大小为1的数组!该标准还包括以下潜台词:“两个对象在内存中可以是相邻的,因为它们是更大数组的相邻元素或结构的相邻成员,并且在它们之间没有填充,或者因为实现选择了这样放置它们,即使它们不相关。”@Lundin True,然而,引用不是OP问题的一部分,也不是这个答案表明一个可以。重新“STD::字节”:这个问题是标记C,而不是C++。