C / C ++ 'da uzun uzun


84

Bu kodu GNU'nun C ++ derleyicisinde deniyorum ve davranışını anlayamıyorum:

#include <stdio.h>;

int main()
{
    int  num1 = 1000000000;
    long num2 = 1000000000;
    long long num3;
    //num3 = 100000000000;
    long long num4 = ~0;

    printf("%u %u %u", sizeof(num1), sizeof(num2), sizeof(num3));
    printf("%d %ld %lld %llu", num1, num2, num3, num4);
    return 0;
}

Yorumlanan satırı kaldırdığımda kod derlenmiyor ve bir hata veriyor:

hata: tamsayı sabiti uzun tip için çok büyük

Ancak, kod olduğu gibi derlenir ve çalıştırılırsa, 10000000000'den çok daha büyük değerler üretir.

Neden?


8
Şimdi çok geç olabilir ama gelecekteki okuyucular için kullanmanızı <stdint.h>ve kullanmanızı öneririm uint64_t. 64 bitlik bir değer görüntülemek içinprintf( "%" PRIu64 "\n", val);
enthusiasticgeek

@enthusiasticgeek <stdint.h>dahil,uint64_t a = 0xffffffffffffff; printf( "%" PRIu64 "\n",a ); : error: expected ‘)’ before ‘PRIu64’ printf( "%" PRIu64 "\n",a ); :: warning: spurious trailing ‘%’ in format [-Wformat=] printf( "%" PRIu64 "\n",a );
Herdsman

Yanıtlar:


148

100000000000 harfleri değişmez bir tamsayı sabiti oluşturur, ancak değer tür için çok büyük int. Değişmez bilginin türünü değiştirmek için bir sonek kullanmanız gerekir, yani

long long num3 = 100000000000LL;

Son ek LL, değişmezi türe dönüştürür long long. C, bunu soldaki tipten sonuçlandıracak kadar "akıllı" değildir, tip, kullanıldığı bağlamın değil, literalin kendisinin bir özelliğidir.


47
Geri Bu cevap yazıldığı zaman muhtemelen doğru, ama şimdi C ++ standart hiçbir sonek ile bir tamsayı sabitin türü ilk olduğunu söylüyor int, long intve long long inthangi değeri temsil edilebilir. [C ++ §2.14.2 / 2] Bu nedenle artık 'LL' son ekini diğer türler için çok büyük olan bir tam sayıya eklemeye gerek yoktur.
bames53

8
Bunun daha önce bir problem olmasının nedeni, C ++ 'nın atanan değişkenin türünden değişmez türü belirleyecek kadar' akıllı 'olmaması değildi, basitçe derleyici uzantısının genişletilmiş tamsayıyı uygulamamasıydı. standart dille iyi çalışacak şekilde yazın. C ++ artık herhangi bir genişletilmiş tamsayı türünün standartla daha iyi entegre olmasını sağlayacak kurallara sahiptir: open-std.org/jtc1/sc22/wg21/docs/papers/2006/n1988.pdf
bames53

4
@unwind Cevabın bu önerilere göre düzeltilmesi gerektiğini düşünüyorum.
Antonio

26

Deneyin:

num3 = 100000000000LL;

Ve BTW, C ++ 'da bu bir derleyici uzantısıdır, standart uzun uzun tanımlamaz, bu C99'un bir parçasıdır.


11
C ++ 11 artık uzun uzun tanımlıyor
Mohamed El-Nakib

4

Hangi modda derlediğinize bağlıdır. long long, C ++ standardının bir parçası değildir, yalnızca (genellikle) uzantı olarak desteklenir. Bu, değişmez değerlerin türünü etkiler. İnt yeterince büyükse, son eki olmayan ondalık tam sayı değişmezleri her zaman int türündedir sayıyı temsil kadar , aksi takdirde uzunsa . Sayı uzun süre çok büyükse, sonuç uygulama tanımlıdır (muhtemelen geriye dönük uyumluluk için kısaltılmış bir dizi long int türü). Bu durumda, uzun uzun uzantıyı etkinleştirmek için (çoğu derleyicide) LL sonekini açıkça kullanmanız gerekir.

Bir sonraki C ++ sürümü, kuvvetin gerçek türünün en az uzun olmasını açıkça istemediğiniz sürece herhangi bir son eke ihtiyacınız olmayacak şekilde resmi olarak uzun süre destekleyecektir. Sayı uzun olarak gösterilemezse, derleyici, LL son eki olmadan bile otomatik olarak uzun uzun kullanmayı deneyecektir. Bunun C99'un davranışı olduğuna inanıyorum.


1

Kodunuz burada iyi bir şekilde derleniyor (bu satır yorumlanmamış olsa bile.

num3 = 100000000000000000000;

uyarıyı almaya başlamak için.


Hangi derleyici? C ++ 'da, bir tamsayı değişmezi, uyduğu int veya long değerinden daha küçüktür. C99'da, int'in en küçüğü, long, long long'dur. Bu nedenle, standart olmayan bir uzantı olarak uzun süre C ++ 'ya cıvatalandığında, derleyiciniz de değişmez değerler için C99 kurallarını benimsemiştir.
Steve Jessop

64bit linux sisteminde gcc sürüm 4.3.2 (Debian 4.3.2-1.1).
Omry Yadan

@SteveJessop Belki biraz geç: ama uzun mutlaka 64 bit DEĞİLDİR. Çoğu zaman öyle, ama her yerde olacağına dair hiçbir garantiniz yok. Sahip olduğunuz tek garanti, en azından int kadar büyük olmasıdır, bu da en azından kısa int kadar büyüktür ve bu da en azından bir char kadar büyüktür. Son olarak, karakter, uygulamanın temel karakter kümesindeki (tipik olarak 8 bit) her karakteri temsil edecek kadar büyük olarak tanımlanır .
pauluss86

@ pauluss86: Garantilerden bahsetmiyordum. Omry, 64 bit Debian sisteminde gcc 4.3.2 kullandığını söyledi. Bunun gördüklerini açıkladığını gözlemledim, çünkü (genel bir bilgi olarak biliyordum) gcc bu tür sistemlerde varsayılan olarak longo işletim sisteminin LP64 ABI ile uyumlu bir 64 bit kullanmak üzere yapılandırıldı .
Steve Jessop

@SteveJessop Yorumunuzun yanlış olduğunu önermiyorum! Sadece uzun bir her yerde her zaman 64 bit olduğu varsayımının ne yazık ki pek çok insanın düşündüğüne dikkat çekmek tehlikeli.
pauluss86
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.