Ardışık diziler

Aug 26 2020

C18 standardındaki bir cümleyi merak ediyorum:

İki işaretçi, ancak ve ancak ikisi de boş işaretçilerse, her ikisi de aynı nesneye işaretçilerse (bir nesneye işaretçi ve başlangıcında bir alt nesne dahil) veya işleve işaret ederse, her ikisi de aynı dizinin son öğesinden bir geçmişe işaretçilerdir. nesne ya da bir tek dizi nesnesinin sonuna geçen bir bir işaretçidir ve diğer bir başlangıcına bir işaretçidir farklı bir dizi nesne olur hemen önce aşağıdaki adres alanını dizi nesne. § 6.5.9 6

Neden diziyi takip eden nesnenin mutlaka başka bir dizi olması gerekiyor? Dizi temel türü ile aynı türde bir nesne olamaz mı (bir inthemen ardından gelen gibi int[])?

Bu kodu denediğime şaşmamalı:

#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;
}

Ve eşit puanlar verir. Bu davranış hiç garanti edilmiyor mu, sadece uygulama tanımlı bir tesadüf mü?

Yanıtlar

24 chux-ReinstateMonica Aug 26 2020 at 17:41

OP: Neden diziyi takip eden nesnenin mutlaka başka bir dizi olması gerekiyor?

O değil. "... farklı bir dizinin başlangıcı ..." bir basitleştirmedir. Sonraki özellik şudur:

Bu işleçlerin amaçları doğrultusunda, bir dizinin öğesi olmayan bir nesneye işaretçi, öğe türü olarak nesnenin türüne sahip bir uzunluktaki dizinin ilk öğesine bir işaretçi gibi davranır. C17dr § 6.5.9 7


OP: Dizi temel türü ile aynı türden bir nesne olamaz mı (bir 'nin inthemen ardından gelen gibi int[])?

Evet.

8 th33lf Aug 26 2020 at 17:26

İlk olarak, burada dizi belirtmek tek bir nesneyi dışlamaz / yasaklamaz. Bellekteki tek bir nesne, 1 boyutundaki bir diziden ayırt edilemez.

( Düzenleme : İşaretçilere atıfta bulunurken bunu açıkça belirten standarttan bir alıntı için bu yanıtı okuyun )

İkinci olarak, standart, kuralın geçerli olduğu senaryoları gösteren aşağıdaki dipnotla birlikte, alıntı yaptığınız ifadeyi de açıklamaya çalışır:

İki nesne bellekte bitişik olabilir, çünkü bunlar daha büyük bir dizinin bitişik öğeleri veya aralarında dolgusuz bir yapının bitişik elemanlarıdır veya uygulama, ilgisiz olsalar bile bunları yerleştirmeyi seçmiştir.

Hepsini bir araya getirecek olursak, burada standardın söylemeye çalıştığı şey, genel olarak, benzer olmayan nesnelere yönelik iki işaretleyicinin birbirine eşit olmaması gerektiği. Bununla birlikte, bellekteki bir dizi nesnesinin ötesine birini işaret etmek yasal olduğundan, bu konumda farklı bir (dizi) nesnesi varsa, böyle bir işaretçinin bitişik nesneye eşit bir işaretçiye eşit olması yine de yasaldır. Şimdi, hizalama seçenekleri ve doldurma nedeniyle bu konumda geçerli bir nesne olabilir veya olmayabilir, ancak varsa, bu işaretçilerin eşit karşılaştırması kabul edilebilir.

Örneğinizde, diziyi bir karakter olarak değiştirirsem, göstericiler muhtemelen int'i 4 bayta (çoğu 32 veya 64-bit platformda) hizalamayı seçeceği için işaretçiler eşitsizliği karşılaştırır ve böylece dolgu sağlar. Bu davranış hala standarda göre yasaldır.

#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;
}