2016-06-21 64 views
7

ho questa linea:serie di WideChar: Imposta possono avere al massimo 256 elementi

const 
    MY_SET: set of WideChar = [WideChar('A')..WideChar('Z')]; 
È possibile che questo

non compilare, con l'errore:

[Error] Sets may have at most 256 elements

Ma questa linea non compilare ok:

var WS: WideString; 
if WS[1] in [WideChar('A')..WideChar('Z')] then... 

E questo compila anche ok:

const 
    MY_SET = [WideChar('A')..WideChar('Z'), WideChar('a')..WideChar('z')]; 
    ... 
    if WS[1] in MY_SET then... 

Perché è quello?

EDIT: La mia domanda è Perchéif WS[1] in [WideChar('A')..WideChar('Z')] compila? e perché compili MY_SET = [WideChar('A')..WideChar('Z'), WideChar('a')..WideChar('z')];? non sono anche loro bisogno di applicare alle regole set?

+0

Il secondo codice ha solo 26 elementi. Molto più semplice da usare> = e <= qui. Si noti che il proprio codice non riconosce caratteri non inglesi. –

+0

@David, Il primo codice non ha anche 26 elementi? "Prendi nota che il tuo codice non riconosce caratteri non inglesi." Devo controllare i caratteri ISO validi. solo i caratteri inglesi sono validi. – zig

+1

Fintanto che gli elementi stessi sono inferiori a 256, la seconda espressione è valida. La prima espressione dichiara un set più grande di 256 dimensioni (set di WideChar). –

risposta

11

Un insieme valida deve obbedire a due regole:

  1. Ogni elemento in un insieme deve avere un valore ordinale inferiore a 256.
  2. Il set non deve contenere più di 256 elementi.
MY_SET: set of WideChar = [WideChar('A')..WideChar('Z')]; 

Qui si dichiara un tipo set (Set of WideChar) che ha più di 256 elementi -> errore di compilazione.

if WS[1] in [WideChar('A')..WideChar('Z')] 

Qui, il compilatore vede WideChar('A') come valore ordinale. Questo valore e tutti gli altri valori nell'insieme sono inferiori a 256. Questo è ok con la regola 1.

Il numero di elementi univoci sono anche entro i limiti (Ord ('Z') - Ord ('A') + 1) , così passa la seconda regola.

MY_SET = [WideChar('A')..WideChar('Z'), WideChar('a')..WideChar('z')]; 

Qui si dichiara un set che soddisfa anche i requisiti di cui sopra. Si noti che il compilatore vede questo come un insieme di valori ordinali, non come set of WideChar.

+1

Interessante, nel secondo caso (se WS [1] in ,,,), come funziona il confronto? –

+0

@TomBrunberg, non vi è alcuna differenza oltre al fatto che il compilatore utilizza la dimensione del parametro sinistro nel confronto con un elemento di dimensione dimensione byte. –

+1

@zig Quindi l'errore è nel * MY_SET: set di parte WideChar *, non in * [WideChar ('A') .. WideChar ('Z')] * –

2

Un set non può contenere più di 256 elementi.
Anche con così pochi elementi il ​​set utilizza già 32 byte.

Dalla documentazione:

A set is a bit array where each bit indicates whether an element is in the set or not. The maximum number of elements in a set is 256, so a set never occupies more than 32 bytes. The number of bytes occupied by a particular set is equal to

(Max div 8) - (Min div 8) + 1

Per questo motivo solo set di byte, (ANSI) char, boolean e enumerazioni con meno di 257 elementi sono possibili.
Poiché widechar utilizza 2 byte, può avere 65536 valori possibili.
Un set di widechar occuperebbe 8Kb, troppo grande per essere pratico.

type 
    Capitals = 'A'..'Z'; 

const 
    MY_SET: set of Capitals = [WideChar('A')..WideChar('Z')]; 

Compilerà e funzionerà allo stesso modo.

Sembra un po 'sciocco usare widechar se il codice ignora l'unicode.
Come sono state riconosciute solo le capitali inglesi, non si tiene conto di impostazioni locali diverse.

In questo caso sarebbe meglio usare il codice come

if (AWideChar >= 'A') and (AWideChar <= 'Z') .... 

che funziona indipendentemente dal numero di caratteri cadono nel mezzo.
Ovviamente è possibile incapsulare questo in una funzione per risparmiare durante la digitazione.

Se si insiste per avere grandi insiemi, vedere questa risposta: https://stackoverflow.com/a/2281327/650492

+2

Ma perché "se WS [1] in [WideChar ('A') .. WideChar ('Z')]' compila? e perché 'MY_SET = [WideChar ('A') .. WideChar ('Z'), WideChar ('a') .. WideChar ('z')];' compila? non si applicano anche alle regole di 'set'? qual è la differenza? – zig

+4

Il compilatore converte 'WideChar ('A')' in un valore ordinale che è inferiore a 256. Se si inserisce un valore maggiore di quello, il compilatore si lamenterà. Ora il compilatore ha un insieme valido con gli elementi +1 di Ord ('Z') - Ord ('A'). –