Hangi platformlarda 8 bit karakterden başka bir şey var?


136

Arada sırada, SO'daki biri char(aka 'bayt') mutlaka 8 bit olmadığını belirtiyor .

8-bit charneredeyse evrensel gibi görünüyor . Anaakım platformlar için, charpiyasadaki canlılığını sağlamak için 8 bitlik bir şey olması gerektiğini düşünürdüm .

Hem şimdi hem de tarihsel olarak, hangi platformlar char8 bit olmayan bir platform kullanıyor ve neden "normal" 8 bitten farklı olacaklar?

Kod yazarken ve platformlar arası desteği düşünürken (örneğin, genel kullanım kütüphaneleri için), 8 bit olmayan platformlara ne tür bir önem verilmelidir char?

Geçmişte char, 16 bit olan bazı Analog Cihazlar DSP'leriyle karşılaştım . DSP'ler sanırım biraz niş bir mimari. (Sonra tekrar, el ile kodlanmış montajcı mevcut C derleyicilerinin yapabileceklerini kolayca yener, bu yüzden bu platformda C ile pek fazla deneyim elde edemedim.)


9
CDC Cyber ​​serisinin 6/12 bit kodlaması vardı. En popüler karakterler 6 bit idi. Kalan karakterler 12 bit kullanıyordu.
Thomas Matthews

2
PDP-11 onu çiviledi. Bir karakterin karakterde kodlanabileceği düşüncesi ciddidir.
Hans Passant

7
"PDP-11 onu çiviledi" - Yani C ilk PDP-11 için 8 bit bayt ile uygulandığı için mi? Ancak C daha sonra 9 bit baytlı Honeywell makineleri için uygulandı. Bkz. K&R sürüm 1. Ayrıca, karakter hakkında değil char (yani bayt) hakkında soru sorulmuştur (sorulmamış bir şeyi kodlayan bir veya daha fazla bayt).
Windows programcısı

6
DEC-10 ve DEC-20'nin 36 bit sözcükleri vardı. Kelime başına beş 7 bitlik ASCII karakteri oldukça yaygındı. Ayrıca altı adet 6-bit karakter kullanılmıştır.
David R Tribble

3
@CraigMcQueen: Doğru hatırlıyorsam, Atmel mikrodenetleyicileri için CodeVision, char
vsz

Yanıtlar:


80

charaynı zamanda örneğin OMAP2'de ortaya çıkan Texas Instruments C54x DSP'lerde 16 bit. 16 ve 32 bitlik başka DSP'ler de var char. Sanırım 24 bitlik bir DSP bile duydum, ama ne olduğunu hatırlayamıyorum, belki de hayal ettim.

Başka bir husus POSIX'in zorunlu kılınmasıdır CHAR_BIT == 8. POSIX kullanıyorsanız bunu varsayabilirsiniz. Daha sonra birisinin kodunuzu POSIX'in neredeyse bir uygulamasına taşıması gerekiyorsa, bu, kullandığınız işlevlere sahip olmak için farklı bir boyutta olur char, bu onların kötü şanslarıdır.

Bununla birlikte, genel olarak, konuyu çözmek her zaman onu düşünmekten daha kolaydır. Sadece yazın CHAR_BIT. Tam 8 bitlik bir tür istiyorsanız, kullanın int8_t. Kodunuz, beklemediğiniz bir boyutu sessizce kullanmak yerine, bir tane sağlamayan uygulamalarda derleme yapamaz. En azından, bunu varsaymak için iyi bir nedenim olan bir davaya isabet edersem, iddia ediyorum.


2
TI C62xx ve C64xx DSP'lerde de 16 bit grafik bulunur. (uint8_t bu platformda tanımlanmamıştır.)
myron-semack

7
Ses işleme için birçok DSP, 24 bitlik makinelerdir; BelaSigna Yarı üzerinde gelen DSP (bunlar AMI Yarı satın sonra); DSP56K / Senfoni Ses Freescale adlı TTP'ler (onlar Motorola kapalı bükülmüş edildi sonra).
David Cary

2
@msemack C64xx, 8/16/32/40 ve 8bit karakter için donanıma sahiptir
user3528438

4
Aksine assert()(demek istediğin buysa), ben kullanacağım #if CHAR_BIT != 8... #error "I require CHAR_BIT == 8"...#endif
Keith Thompson

1
@KeithThompson Kullanmamak için herhangi bir neden var mı static_assert()?
Qix - MONICA

37

Kod yazarken ve platformlar arası desteği düşünürken (örneğin, genel kullanım kütüphaneleri için), 8 bitlik karakter olmayan platformlara ne tür bir önem verilmelidir?

Kurallara göre oynadığı gibi bir şeyi "dikkate almaya değer" değildir. Örneğin, C ++ 'da standart tüm baytların "en az" 8 bit içereceğini söylüyor. Kodunuz baytların tam olarak 8 bit olduğunu varsayarsa, standardı ihlal edersiniz.

Bu şimdi aptalca görünebilir - " elbette tüm baytlarda 8 bit var!", Dediğini duydum. Ancak pek çok akıllı insan, garanti olmayan varsayımlara dayanıyordu ve sonra her şey bozuldu. Tarih bu örneklerle doludur.

Örneğin, 90'ların başındaki çoğu geliştirici, sabit sayıda döngü alan belirli bir işlem yapılmayan CPU zamanlama gecikmesinin sabit bir saat süresine sahip olacağını varsayıyordu, çünkü çoğu tüketici CPU'su yaklaşık olarak güçte eşdeğerdi. Ne yazık ki, bilgisayarlar çok hızlı bir şekilde hızlandı. Bu, ironik bir şekilde, bilgisayarı yavaşlatmak olan "Turbo" düğmeleriyle kutuların yükselişini sağladı, böylece zaman geciktirme tekniğini kullanan oyunlar makul bir hızda oynatılabildi.


Bir yorumcu, standartta karakterin en az 8 bit olması gerektiğini söylediğini sordu. Bölüm 5.2.4.2.1 . Bu bölüm, CHAR_BITadreslenebilir en küçük varlıktaki bit sayısını tanımlar ve varsayılan değeri 8'dir.

Uygulama tanımlı değerleri, aynı işaretle gösterilenlere eşit veya daha büyük (mutlak değer) olmalıdır.

Bu nedenle, 8 veya daha yüksek herhangi bir sayı, bir uygulamanın yerine geçmeye uygundur CHAR_BIT.


6
En az 20 yıldır bir Turbo düğmesi görmedim - sence bu soruya gerçekten uygun mu?
Mark Ransom

29
@Mark Ransom: Bütün mesele bu. Geliştiriciler genellikle şu anda doğru gibi görünen, ancak başlangıçta göründüğünden çok daha titiz olan varsayımlara güvenir. (Zamanlarda yaptığım sayısını Can o hata!) Gereksiz varsayımda bulunmak değil ve kesinlikle onlar sanki bir dil standardına göre garanti edilmez varsayımlar yapmamaya ağrılı hatırlatma olmalı Turbo düğmesi değişmez gerçekler.
John Feminella

1
Baytın en az 8 biti olduğunu söyleyen C ++ Standardında yer verebilir misiniz? Bu yaygın bir inançtır, ancak ben bunu Standartta bulamadım. Standard'da bulduğum tek şey, hangi karakterlerin char64'ten daha fazla temsil edilebileceği , ancak 128'den az 7 bitin yeterli olacağı.
Adam Badura

6
Bölüm 18.2.2 bunun için C standardını çağırır. C standardında bölüm 7.10 ve sonra bölüm 5.4.2.4.1. Sayfa 22 C standardında.
Windows programcısı

2
Yani diğer cevaplar ve yorumlar 5 bit, 6 bit ve 7 bit baytlık makinelerden bahsediyor. Bu, o makinede standarda uygun bir C programı çalıştıramayacağınız anlamına mı geliyor?
Jerry Jeremiah

34

36 bit mimariye sahip makinelerde 9 bit bayt vardır. Wikipedia'ya göre, 36 bit mimariye sahip makineler şunları içerir:

  • Dijital Ekipman Şirketi PDP-6/10
  • IBM 701/704/709/7090/7094
  • UNIVAC 1103 / 1103A / 1105/1100/2200,

7
Ayrıca Honeywell makineleri, örneğin C'nin uygulandığı ikinci makine gibi. Bkz. K&R sürüm 1.
Windows programcısı

5
Aslında, Dec-10'un da 6-bit karakterleri vardı - bunlardan 6'sını 36-bit bir kelimeye (eski Dec-10 programcı konuşuyor)

2
DEC-20, TOPS-20 O / S'de 36 bit sözcük başına beş 7 bit ASCII karakteri kullandı.
David R Tribble

3
Bu şaka aslında Unicode'u bu mimaride desteklemek için uygulandı.
Joshua

9
Sekizli'nin gerçekte kullanılmasının nedeninin, 3 sekizlik basamağın düzgün bir şekilde 9 bitlik bir baytı temsil etmesi olduğunu düşünüyorum, tıpkı bugün genellikle onaltılık kullandığımız gibi, iki onaltılı basamak düzgün bir şekilde 8 bitlik bir baytı temsil ediyor.
bames53

18

Bunlardan birkaçının farkındayım:

  • DEC PDP-10: değişken, ancak çoğu zaman 7 bit karakter 36 bitlik kelime başına 5 veya başka bir deyişle 9 bit karakter, sözcük başına 4
  • Kontrol Verileri ana çerçeveleri (CDC-6400, 6500, 6600, 7600, Cyber ​​170, Cyber ​​176 vb.) 60 bitlik kelime başına 10'luk paketlenmiş 6 bitlik grafikler.
  • Unisys mainframes: 9 bit / bayt
  • Windows CE: `char 'türünü hiç desteklemiyor - bunun yerine 16 bit wchar_t gerekiyor

2
@ephemient: PDP-10 / DecSystem 10 / DecSystem 20 için en az bir (standart öncesi) C derleyicisi olduğundan eminim, ancak CDC ana çerçeveleri için bir C derleyicisine çok şaşırırdım ( öncelikle sayısal işler için kullanıldığından, Fortran derleyicisi orada en büyük şeydi). Diğerlerinin C derleyicileri olduğundan eminim.
Jerry Coffin

3
Windows CE derleyicisi bu chartürü gerçekten desteklemedi mi? Sistem kitaplıklarının yalnızca dizeleri alan işlevlerin geniş karakter sürümlerini desteklediğini ve en azından WinCE'nin bazı sürümlerinin, karakter dizisi işleme işlemini durdurmak için strlen gibi ANSI dize işlevlerini kaldırdığını biliyorum. Ama gerçekten hiç bir char türü yoktu? Ne oldu sizeof(TCHAR)? Malloc ne tür geri döndü? Java bytetürü nasıl uygulandı?
Steve Jessop

10
Windows CE, bayt olan char'ı destekler. Bkz. Craig McQueen'in Richard Pennington'un cevabı hakkındaki yorumu. Baytlar, her yerde hangi boyutta olursa olsun, Windows CE'de her yerde olduğu kadar gereklidir.
Windows programcısı

2
PDP-10 için C'nin en az iki uygulaması vardır (vardı?): KCC ve bir gcc portu ( pdp10.nocrew.org/gcc ).
AProgrammer

3
C standardı, 36 bit sözcük başına 5 paketlenmiş 7 bit karakterlere izin vermez (PDP-10 için belirttiğiniz gibi) veya Kontrol Verileri ana karelerinde belirttiğiniz gibi 6 bit karakterlere izin vermez. Bkz. Parashift.com/c++-faq-lite/intrinsic-types.html#faq-26.6
Ken Bloom

15

Tamamen taşınabilir bir kod diye bir şey yoktur. :-)

Evet, çeşitli bayt / karakter boyutları olabilir. Evet, oldukça sıradışı değerleri ile platformlar için C / C ++ uygulamaları olabilir CHAR_BITve UCHAR_MAX. Evet, bazen karakter boyutuna bağlı olmayan bir kod yazmak mümkündür.

Ancak, neredeyse tüm gerçek kodlar bağımsız değildir. Örneğin, ağa ikili mesajlar gönderen bir kod yazıyor olabilirsiniz (protokol önemli değildir). Gerekli alanları içeren yapıları tanımlayabilirsiniz. Daha seri hale getirmek zorunda. Bir yapıyı bir çıkış arabelleğine ikili olarak kopyalamak taşınabilir değildir: genellikle platform için bayt sırasını veya yapı üyelerinin hizalamasını bilmezsiniz, bu nedenle yapı sadece verileri tutar, ancak verilerin serileştirilmesi gerektiğini açıklamaz .

Tamam. Bayt sırası dönüşümleri gerçekleştirebilir ve yapı elemanlarını (örneğin uint32_tveya benzeri) memcpyarabelleğe taşıyabilirsiniz . Neden memcpy? Hedef adres düzgün hizalanmadığında 32 bit (16 bit, 64 bit - fark yok) yazmanın mümkün olmadığı birçok platform olduğundan.

Yani, taşınabilirliği elde etmek için zaten çok şey yaptınız.

Ve şimdi son soru. Bir tamponumuz var. Veriler TCP / IP ağına gönderilir. Bu tür ağlar 8 bit bayt alır. Soru şu: tamponun ne tür olması gerekir? Karakterleriniz 9 bit ise? 16 bitlerse? 24? Belki her karakter ağa gönderilen bir 8-bit bayta karşılık gelir ve sadece 8 bit kullanılır? Veya 24/16/9-bit karakterlere birden fazla ağ baytı paketlenmiş olabilir? Bu bir soru ve tüm durumlara uyan tek bir cevap olduğuna inanmak zor. Birçok şey, hedef platform için soket uygulamasına bağlıdır.

Ne hakkında konuşuyorum. Genellikle kod belirli ölçüde taşınabilir hale getirilebilir . Kodu farklı platformlarda kullanmayı düşünüyorsanız bunu yapmanız çok önemlidir. Bununla birlikte, bu önlemin ötesinde taşınabilirliği geliştirmek , çok fazla çaba gerektiren ve genellikle çok az şey veren bir şeydir , çünkü gerçek kod neredeyse her zaman diğer koda bağlıdır (yukarıdaki örnekte soket uygulaması). 8 bit dışındaki baytlarla platformlarda çalışma kod yeteneğinin yaklaşık% 90'ı için neredeyse işe yaramaz olduğundan, 8 bit'e bağlı bir ortam kullandığından eminim. Sadece bayt boyutunu kontrol edin ve derleme zamanı iddiasını gerçekleştirin. Son derece alışılmadık bir platform için neredeyse kesinlikle çok fazla yeniden yazmak zorunda kalacaksınız.

Ancak kodunuz "bağımsız" ise - neden olmasın? Farklı bayt boyutlarına izin verecek şekilde yazabilirsiniz.


4
Eğer kişi unsigned chardeğer başına bir oktet saklarsa , kod sekizli sekansları daha büyük tamsayı tiplerine / onlardan dönüştürmek için vardiyalar yerine takma numaralar kullanmadıkça taşınabilirlik problemleri olmamalıdır. Şahsen, C standardının, charher bir öğe için sabit garantili kullanılabilir sayıda bit (8 başına unsigned char, 16 başına unsigned shortveya 32 başına unsigned long) depolayan daha kısa tiplerden (en tipik olarak ) tamsayıları paketlemek / paketinden çıkarmak için gerçekleri tanımlaması gerektiğini düşünüyorum .
supercat



5

Örneğin, C ve C ++ programlama dilleri baytı "yürütme ortamının temel karakter kümesinin herhangi bir üyesini tutacak kadar büyük adreslenebilir veri birimi" olarak tanımlamaktadır (C standardının 3.6 maddesi). C karakter integrali veri türünün en az 8 bit içermesi gerektiğinden (madde 5.2.4.2.1), C cinsinden bir bayt en azından 256 farklı değer tutabilir. C ve C ++ 'nın çeşitli uygulamaları bir baytı 8, 9, 16, 32 veya 36 bit olarak tanımlar

Alıntı sahibi http://en.wikipedia.org/wiki/Byte#History

Diğer diller hakkında emin değilim.

http://en.wikipedia.org/wiki/IBM_7030_Stretch#Data_Formats

Bu makinedeki bir baytı değişken uzunluk olarak tanımlar


1
"Diğer diller hakkında emin değilim" - tarihsel olarak, çoğu dil makinenin mimarisinin kendi bayt boyutunu tanımlamasına izin verdi. Aslında, standart 8'de bir alt sınır belirleyene kadar tarihsel olarak C de öyle.
Windows programcısı

4

DEC PDP-8 ailesi 12 bitlik bir kelimeye sahipti, ancak çıkış için genellikle 8 bit ASCII kullandınız (çoğunlukla bir Teletype'da). Ancak, 2 karakter tek bir 12 bit sözcükle kodlamanıza izin veren 6-BIT karakter kodu da vardı.


3

Birincisi, Unicode karakterler 8-bit'ten daha uzundur. Daha önce de belirtildiği gibi, C spesifikasyonu veri türlerini minimum boyutlarına göre tanımlar. Kullanımı sizeofve içindeki değerlerlimits.hVeri türlerinizi sorgulamak ve yapılandırma ve mimariniz için tam olarak hangi boyutta olduklarını keşfetmek istiyorsanız .

Bu nedenle, aşağıdaki gibi veri türlerine bağlı kalmaya çalışıyorum uint16_t belirli bir bit uzunluğuna sahip bir veri türüne ihtiyaç duyduğum .

Düzenle: Üzgünüm, başlangıçta sorunuzu yanlış okudum.

C spec bir charnesnenin "yürütme karakter kümesinin herhangi bir üyesini saklamak için yeterince büyük" olduğunu söylüyor . limits.hminimum 8 bit büyüklüğünü listeler, ancak tanım birchar açıklığın .

Bu nedenle, a charen azından mimarinizin yürütme kümesindeki en büyük karakter (genellikle en yakın 8 bitlik sınıra yuvarlanır) kadardır. Mimarinizde daha uzun opcode varsa,char boyutunuz daha uzun olabilir.

Tarihsel olarak, x86 platformunun op kodu bir bayt uzunluğundaydı, bu yüzden charbaşlangıçta 8 bitlik bir değerdi. Mevcut x86 platformları bir bayttan daha uzun opcodları destekler, ancak charprogramcıların (ve mevcut x86 kodunun büyük hacimlerinin) koşullandırıldığı için 8 bit uzunluğunda tutulur.

Çoklu platform desteği hakkında düşünürken, içinde tanımlanan türlerden yararlanın stdint.h. Eğer bir uint16_t (örneğin) kullanıyorsanız, o zaman emin bu değer o 16 bit değeri karşılık gelir olsun bir etmek, ne olursa olsun mimarisine işaretsiz 16 bit değerdir olabilir char, short,int , ya da başka bir şey. Sıkı çalışmanın çoğu derleyici / standart kütüphanelerinizi yazan kişiler tarafından yapılmıştır.

Tam boyutunu bilmeniz gerekiyorsa char, bunu gerektiren bazı düşük seviyeli donanım manipülasyonu yaptığınız için, genellikle chardesteklenen tüm platformlarda (genellikle 16 bit yeterlidir) tutacak kadar büyük bir veri türü kullanıyorum ve convert_to_machine_chartam makine temsiline ihtiyacım olduğunda rutin bir değer . Bu şekilde, platforma özgü kod arabirim işlevi ile sınırlıdır ve çoğu zaman normal kullanabilirim uint16_t.


2
Soru karakterler hakkında soru sormadı (Unicode olsun ya da olmasın). Bayt olan char'ı sordu.
Windows programcısı

1
Ayrıca, yürütme karakter kümesinin opcodes ile ilgisi yoktur, yürütmede kullanılan karakter kümesidir, çapraz derleyicileri düşünün.
ninjalj

"Tarihsel olarak, x86 platformunun op kodu bir bayt uzunluğundaydı": ne kadar tatlı. Tarihsel olarak C, x86 icat edilmeden çok önce bir PDP-11 (1972) üzerinde geliştirildi (1978).
Martin Bonner, Monica

3

8 bitlik olmayan char'lı platformlara ne tür bir dikkat göstermeye değer?

sihirli sayılar, örneğin kaydırma yaparken ortaya çıkar;

bunların çoğu CHAR_BIT ve örneğin 8 ve 255 yerine UCHAR_MAX (veya benzeri) kullanılarak oldukça basit bir şekilde ele alınabilir.

umarım uygulamanız bunları tanımlar :)

bunlar "ortak" konular .....

başka bir dolaylı sorun var:

struct xyz {
   uchar baz;
   uchar blah;
   uchar buzz; 
}

bu "yalnızca" bir platformda 24 bit alabilir, ancak başka bir yerde 72 bit alabilir .....

eğer her uchar "bit bayrakları" tutmuşsa ve her uchar şu anda kullandığınız 2 "önemli" bit veya bayrağa sahipse ve bunları "netlik" için sadece 3 uchars halinde organize ettiyseniz, o zaman göreceli olarak "daha israflı" olabilir. 24-bit uchars ile bir platform .....

hiçbir şey bitfields çözemez, ama dikkat edilmesi gereken başka şeyler var ....

Bu durumda, sadece tek bir enum aslında ihtiyacınız olan "en küçük" boyutlu tamsayı almak için bir yol olabilir ....

belki gerçek bir örnek değil, ama bu gibi şeyler "biraz" taşıma / bazı kod ile oynarken .....

sadece bir uchar "normalde" beklendiği gibi üç kat büyükse, 100 gibi yapıları bazı platformlarda çok fazla bellek israf ..... ..... "normalde" büyük bir anlaşma değildir .... .

bu yüzden bir uchar'ın bir platformda, mevcut RAM'e göre, başka bir platforma göre "çok israflı olmadığı" varsayımı nedeniyle işler hala "kırılabilir" veya bu durumda "çok fazla bellek harcar" ... ..

sorun, örneğin ints veya diğer tipler için daha belirgin olabilir, örneğin 15 bit'e ihtiyaç duyan bir yapıya sahipsiniz, bu yüzden bir int'e yapışırsınız, ancak başka bir platformda int 48 bit veya başka bir şeydir .... .

"normalde" 2 uchars kırmak olabilir, ama örneğin 24-bit uchar ile sadece bir gerekir .....

böylece bir enum daha iyi bir "genel" bir çözüm olabilir ....

yine de bu bitlere nasıl eriştiğinize bağlıdır :)

Bu nedenle, başlarını arkada "tasarım kusurları" olabilir .... kod bir uchar veya uint boyutundan bağımsız olarak hala iyi çalışabilir / çalışsa bile ...

kodunuzda "sihirli sayılar" olmamasına rağmen dikkat edilmesi gereken şeyler var ...

umarım bu mantıklıdır :)


1
...ne? Neden enumdiğer yerel türlerden daha küçük olduğunu düşünüyorsunuz ? Varsayılan olarak aynı depolama alanını kullandığını intbiliyor musunuz? "15 bite ihtiyaç duyan bir yapınız var, bu yüzden bir int'e yapışıyorsunuz, ancak başka bir platformda int 48 bit veya her neyse ..." - yani #include <cstdint>ve int16_tbit kullanımını en aza indirmenin en iyi şansı için . Tüm bu elipsler arasında ne söylediğini düşündüğünden gerçekten emin değilim.
underscore_d

1

ints 16 bit (pdp11 vb.) idi. 32 bit mimarilere gitmek zordu. İnsanlar iyileşiyor: Hiç kimse bir işaretçinin daha uzun süre sığacağını varsayar (doğru değil mi?). Veya dosya ofsetleri veya zaman damgaları veya ...

8 bit karakterler zaten bir anakronizmdir. Dünyanın tüm karakter setlerini tutmak için zaten 32 bite ihtiyacımız var.


2
Doğru. charUnicode günlerinde bu isim biraz tuhaf. Dosya depolama, ağ iletişimi gibi ikili verilerle uğraşırken 8 bitlik birimlere (sekizli) önem veriyorum. uint8_tdaha faydalıdır.
Craig McQueen

3
Unicode aslında tam bir 32 bit'e ihtiyaç duymadı. Başlangıçta 31 için planladılar (orijinal UTF-8 çalışmasına bakın), ancak şimdi sadece 21 bit içeren içerikler . Muhtemelen 31 bitin hepsine ihtiyaç duyuyorlarsa kitabı artık
basamayacaklarını fark ettiler

2
@ me22, Unicode başlangıçta 16 bit için planlanmıştı. "Unicode karakterler dilden bağımsız olarak sürekli olarak 16 bit genişliğinde ..." Unicode 1.0.0. unicode.org/versions/Unicode1.0.0/ch01.pdf .
Shannon Severance

1
ISO 10646 başlangıçta 31 bit ve Unicode ISO 10646 ile birleştirildi, bu nedenle Unicode'un 31 bit olduğunu söylemek özensiz olabilir, ancak gerçekte doğru değil. Tam kod tablolarını artık yazdırmadıklarını unutmayın.
prosfilaes
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.