C unsigned char array de șiruri de caractere (Programare, C, Array-Uri, String)

mlstudent a intrebat.

Am un array de șiruri de caractere ca atare

char *T[] = {"0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111", "1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111"};

Când o fac așa, însă, unde fiecare șir este un array de caractere fără semn

unsigned char *T[] = {"0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111", "1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111"};

Primesc eroarea „Initializing ‘unsigned char *’ with an expression of type ‘char[5]’ converteste între pointeri la tipuri de numere întregi cu semn diferit.”. Bănuiesc că asta înseamnă că unele dintre reprezentările lui „0” și „1” care sunt folosite sunt semnate, dar nu sunt sigur de ce/cum să mă ocup de asta. Aș dori să am o matrice de șiruri în care fiecare șir este o matrice de caractere fără semn, mai degrabă decât de caractere cu semn. Poate cineva să mă ajute cu asta?

Notă: acest lucru este pentru o problemă HW, dar nu este problema reală și este doar un pas minor într-una din multele soluții posibile. Totuși, ar fi bine dacă m-ați putea ajuta să o înțeleg fără să-mi dați un răspuns explicit. Mulțumesc.

Comentarii

  • Ca să simplificăm, literalele de șir de caractere sunt de tip char* nu unsigned char*. –  > Por Mysticial.
  • @tuğrulbüyükıșık Recomand cu tărie împotriva turnării pentru a încălca siguranța de tip. –  > Por Mysticial.
  • atunci o matrice de uniuni de uniuni de char + unsigned char funcționează bine, deoarece fiecare va fi de 1 octet, astfel încât endianness nu va fi o problemă. Aliasing? –  > Por huseyin tugrul buyukisik.
  • Este nevoie să facem caracterele fără semn? Ce fel de comparații ați efectua cu ele? –  > Por E_net4 curator.
  • Mysticial are dreptate cu privire la faptul că literalele de șiruri de caractere sunt const char*. Cred că încercați să faceți conversia dintr-un motiv greșit; ați putea descrie problema mai largă pe care o rezolvați? –  > Por Serghei Kalinichenko.
1 răspunsuri
Edwin Buck

Șirurile C, unul dintre multele moduri în care se poate reprezenta un șir de caractere, constau din matrici de char care se termină cu un char care are valoarea null valoare. Asta este ceea ce obțineți din punct de vedere al tipului atunci când aveți „0000” în cod.

Ceea ce doriți este să atribuiți lui „0000” să fie un array de unsigned char terminat cu o linie de sfârșit unsigned char care are valoarea nulă. Având în vedere cu ce porniți, va trebui să faceți o distribuție sau poate să reprezentați datele inițiale într-un mod care nu necesită distribuție.

unsigned char T[][] = { { 0x30, 0x30, 0x30, 0x30, 0x00 }, 
               { 0x30, 0x30, 0x30, 0x31, 0x00 }, 
               { 0x30, 0x30, 0x31, 0x30, 0x00 }, 
               { 0x30, 0x30, 0x31, 0x31, 0x00 }, 
               { 0x30, 0x31, 0x30, 0x30, 0x00 }, 
               { 0x30, 0x31, 0x30, 0x31, 0x00 }, 
               { 0x30, 0x31, 0x31, 0x30, 0x00 }, 
               { 0x30, 0x31, 0x31, 0x31, 0x00 }, 
               { 0x31, 0x30, 0x30, 0x30, 0x00 }, 
               { 0x31, 0x30, 0x30, 0x31, 0x00 }, 
               { 0x31, 0x30, 0x31, 0x30, 0x00 }, 
               { 0x31, 0x30, 0x31, 0x31, 0x00 }, 
               { 0x31, 0x31, 0x30, 0x30, 0x00 }, 
               { 0x31, 0x31, 0x30, 0x31, 0x00 }, 
               { 0x31, 0x31, 0x31, 0x30, 0x00 }, 
               { 0x31, 0x31, 0x31, 0x31, 0x00 }
              };

Principala problemă pe care o văd în această abordare este că elimină cea mai mare parte a avantajului de a avea un șir de caractere în stil C în primul rând. Cu un „string” de tip unsigned char, nu aveți la dispoziție niciuna dintre bibliotecile standard de șiruri de caractere, așa că va trebui să faceți din nou cast la tipurile de șiruri de caractere cu semn dacă doriți să folosiți printfsau orice altă funcție orientată pe șiruri.

Într-adevăr, utilizați doar două valori pentru fiecare poziție posibilă a caracterului „0” și „1”. Cu excepția cazului în care există un motiv imperios pentru a o face într-un șir de caractere, luați în considerare un array de valori booleene pentru a reduce șansele ca un șir de caractere precum „0hello” să ajungă în cod, sau și mai bine dacă ați făcut cunoștință cu câmpurile de biți, utilizați biții dintr-un caracter fără semn ca și câmpuri de biți (renunțând la ideea că aveți de-a face cu șiruri de caractere).

Printre avantajele ultimei tehnici se numără utilizarea unei cantități mai mici de memorie și imposibilitatea ca valoarea să fie alta decât 0 sau 1; cu toate acestea, va trebui să scrieți o mică colecție de rutine pentru a traduce biții împachetați în ceva lizibil pentru oameni.

unsigned char[] = { 0x00, 0x01, 0x02, 0x03, 0x04,
                    0x05, 0x06, 0x07, 0x08, 0x09,
                    0x0A, 0x0B, 0x0C, 0x0D, 0x0E,
                    0x0F };

void displayChar(unsigned char value) {
  switch (value) {
    case 0x00: printf("0000"); break;
    case 0x01: printf("0001"); break;
    case 0x02: printf("0010"); break;
    case 0x03: printf("0011"); break;
... and so on ...

Comentarii

  • Cum ar arăta această soluție care utilizează câmpuri de biți? Cum se utilizează biții dintr-un char fără semn ca câmpuri de biți? –  > Por Willwsharp.
  • @Willwsharp câmpurile de biți sunt doar numere tratate ca biți. Pentru a tasta o constantă literală de biți, se va folosi (avertisment, depinde de standard / depinde de compilator) 0b00100101 Aceasta nu va face ca „tipul” să fie un câmp de biți, care va fi în continuare un char fără semn (deoarece C nu are tipuri de „câmpuri de biți”. Ar fi util doar dacă pozițiile de bit ar fi semnificative, iar formatarea codului ar fi de așa natură încât să evidențieze elementul. De aceea atât de mulți oameni folosesc constante în C pentru a specifica stegulețele 8 == 0b1000 == CAN_READ și acum (stegulețe & CAN_READ) pot fi comparate cu zero (pentru a determina dacă stegulețul CAN READ a fost activat) –  > Por Edwin Buck.
  • Hmm, toate acestea au sens; cred că îmi scapă cum ar putea fi folosit în exemplul de mai sus –  > Por Willwsharp.
  • @Willwsharp înlocuiți char[] de mai sus cu unsigned char[] = { 0b00000000, 0b00000001, 0b00000010, 0b00000011, ... și așa mai departe. 0x07 nu este un „tip hexazecimal” este un tip „unsigned char”, unde biții sunt specificați ca numere hexazecimale. făcând 0b00000111, din nou nu este un „tip binar” este un tip „unsigned char”, unde biții sunt specificați ca numere binare. Prin „a”, din nou, nu este un tip „char”, ci un tip „unsigned char”, în care biții sunt specificați sub forma unui caracter. Acest tip este atașat variabilei. Datele de inițializare promovează doar la un tip corespunzător. –  > Por Edwin Buck.