[successivo] [precedente] [inizio] [fine] [indice generale] [indice ridotto] [indice analitico] [home] [volume] [parte]


Capitolo 598.   C: «inttypes.h»

Il file inttypes.h della libreria standard serve principalmente a completare le funzionalità di stdint.h, per ciò che riguarda la gestione dei valori numerici interi, il cui rango è controllabile. Infatti, il problema principale nell'uso di interi definiti in modo alternativo allo standard del linguaggio C, privo di librerie, sta nell'uso appropriato degli specificatori di conversione nelle funzioni come printf() e scanf(). È proprio per risolvere questo problema che nel file inttypes.h vanno definite, soprattutto, delle macro-variabili da usare in sostituzione degli specificatori di conversione basati sui tipi elementari.

Gli esempi proposti per descrivere la libreria che fa capo al file inttypes.h si riferiscono a quanto già definito nel capitolo 592 a proposito del file stdint.h.

Inizialmente, il file inttypes.h deve includere stdint.h, inoltre dichiara il tipo wchar_t, già descritto nel file stddef.h:

#include <stdint.h>
typedef unsigned int wchar_t;

598.1   Divisione intera con interi di rango massimo

Nel file inttypes.h viene definito il tipo imaxdiv_t che va ad affiancarsi ai tipi div_t, ldiv_t e ldiv_t, definiti nel file stdlib.h. In pratica si tratta di una struttura il cui scopo è quello di contenere il risultato di una divisione, espresso come quoziente e resto, quando il tipo intero usato è quello massimo:

typedef struct {intmax_t quot; intmax_t rem;} imaxdiv_t;

Il tipo strutturato imaxdiv_t serve alle funzioni imaxdiv() e uimaxdiv(), le quali sono sostanzialmente equivalenti alle altre funzioni ...div() del file stdlib.h:

imaxdiv_t imaxdiv (intmax_t numer, intmax_t denom);
#include <inttypes.h>
imaxdiv_t
imaxdiv   (intmax_t numer, intmax_t denom)
{
    imaxdiv_t d;
    d.quot = numer / denom;
    d.rem = numer % denom;
    return d;
}    

598.2   Macro-variabili in qualità di specificatori di conversione

Come accennato all'inizio del capitolo, per poter usare le funzioni ...printf() e ...scanf(), occorrono degli specificatori di conversione, ma non ne esistono per i tipi interi a rango controllato, pertanto, per questi, servono delle macro-variabili coerenti con il tipo relativo.

Le macro che iniziano per PRI... si usano come parte terminale di specificatori di conversione per la composizione dell'output (...printf()), mentre le macro che iniziano per SCN... sono adatte per l'interpretazione dell'input (...scanf()).

Le macro PRIxn e SCNxn terminano gli specificatori di conversione %...x, per i tipi interi [u]intn_t; le macro PRIxLEASTn e SCNxLEASTn riguardano i tipi [u]int_leastn_t; le macro PRIxFASTn e SCNxFASTn riguardano i tipi [u]int_fastn_t; le macro PRIxMAXn e SCNxMAXn riguardano i tipi [u]intmax_t; le macro PRIxPTRn e SCNxPTRn riguardano i tipi [u]intptr_t.

L'esempio seguente dovrebbe dimostrare il significato di queste macro-variabili, attraverso l'uso di printf():

#include <stdio.h>
#include <inttypes.h>
int
main (int argc, char *argv[])
{
    uint64_t num = INT64_C(1234567890);
    printf ("Il valore della variabile \"num\" corrisponde a "
            "%020" PRIu64 ".\n", num);
    return 0;
}    

Il listato seguente mostra come possono essere dichiarate queste macro-variabili:

// Composizione dell'output.

#define PRId8           "d"
#define PRId16          "d"
#define PRId32          "d"
#define PRId64          "lld"

#define PRIdLEAST8      "d"
#define PRIdLEAST16     "d"
#define PRIdLEAST32     "d"
#define PRIdLEAST64     "lld"

#define PRIdFAST8       "d"
#define PRIdFAST16      "d"
#define PRIdFAST32      "d"
#define PRIdFAST64      "lld"

#define PRIdMAX         "lld"
#define PRIdPTR         "d"

#define PRIi8           "i"
#define PRIi16          "i"
#define PRIi32          "i"
#define PRIi64          "lli"

#define PRIiLEAST8      "i"
#define PRIiLEAST16     "i"
#define PRIiLEAST32     "i"
#define PRIiLEAST64     "lli"

#define PRIiFAST8       "i"
#define PRIiFAST16      "i"
#define PRIiFAST32      "i"
#define PRIiFAST64      "lli"

#define PRIiMAX         "lli"
#define PRIiPTR         "i"

#define PRIo8           "o"
#define PRIo16          "o"
#define PRIo32          "o"
#define PRIo64          "llo"

#define PRIoLEAST8      "o"
#define PRIoLEAST16     "o"
#define PRIoLEAST32     "o"
#define PRIoLEAST64     "llo"

#define PRIoFAST8       "o"
#define PRIoFAST16      "o"
#define PRIoFAST32      "o"
#define PRIoFAST64      "llo"

#define PRIoMAX         "llo"
#define PRIoPTR         "o"

#define PRIu8           "u"
#define PRIu16          "u"
#define PRIu32          "u"
#define PRIu64          "llu"

#define PRIuLEAST8      "u"
#define PRIuLEAST16     "u"
#define PRIuLEAST32     "u"
#define PRIuLEAST64     "llu"

#define PRIuFAST8       "u"
#define PRIuFAST16      "u"
#define PRIuFAST32      "u"
#define PRIuFAST64      "llu"

#define PRIuMAX         "llu"
#define PRIuPTR         "u"

#define PRIx8           "x"
#define PRIx16          "x"
#define PRIx32          "x"
#define PRIx64          "llx"

#define PRIxLEAST8      "x"
#define PRIxLEAST16     "x"
#define PRIxLEAST32     "x"
#define PRIxLEAST64     "llx"

#define PRIxFAST8       "x"
#define PRIxFAST16      "x"
#define PRIxFAST32      "x"
#define PRIxFAST64      "llx"

#define PRIxMAX         "llx"
#define PRIxPTR         "x"

#define PRIX8           "X"
#define PRIX16          "X"
#define PRIX32          "X"
#define PRIX64          "llX"

#define PRIXLEAST8      "X"
#define PRIXLEAST16     "X"
#define PRIXLEAST32     "X"
#define PRIXLEAST64     "llX"

#define PRIXFAST8       "X"
#define PRIXFAST16      "X"
#define PRIXFAST32      "X"
#define PRIXFAST64      "llX"

#define PRIXMAX         "llX"
#define PRIXPTR         "X"

// Interpretazione dell'input.

#define SCNd8           "hhd"
#define SCNd16          "hd"
#define SCNd32          "d"
#define SCNd64          "lld"

#define SCNdLEAST8      "hhd"
#define SCNdLEAST16     "hd"
#define SCNdLEAST32     "d"
#define SCNdLEAST64     "lld"

#define SCNdFAST8       "hhd"
#define SCNdFAST16      "d"
#define SCNdFAST32      "d"
#define SCNdFAST64      "lld"

#define SCNdMAX         "lld"
#define SCNdPTR         "d"

#define SCNi8           "hhi"
#define SCNi16          "hi"
#define SCNi32          "i"
#define SCNi64          "lli"

#define SCNiLEAST8      "hhi"
#define SCNiLEAST16     "hi"
#define SCNiLEAST32     "i"
#define SCNiLEAST64     "lli"

#define SCNiFAST8       "hhi"
#define SCNiFAST16      "i"
#define SCNiFAST32      "i"
#define SCNiFAST64      "lli"

#define SCNiMAX         "lli"
#define SCNiPTR         "i"

#define SCNo8           "hho"
#define SCNo16          "ho"
#define SCNo32          "o"
#define SCNo64          "llo"

#define SCNoLEAST8      "hho"
#define SCNoLEAST16     "ho"
#define SCNoLEAST32     "o"
#define SCNoLEAST64     "llo"

#define SCNoFAST8       "hho"
#define SCNoFAST16      "o"
#define SCNoFAST32      "o"
#define SCNoFAST64      "llo"

#define SCNoMAX         "llo"
#define SCNoPTR         "o"

#define SCNu8           "hhu"
#define SCNu16          "hu"
#define SCNu32          "u"
#define SCNu64          "llu"

#define SCNuLEAST8      "hhu"
#define SCNuLEAST16     "hu"
#define SCNuLEAST32     "u"
#define SCNuLEAST64     "llu"

#define SCNuFAST8       "hhu"
#define SCNuFAST16      "u"
#define SCNuFAST32      "u"
#define SCNuFAST64      "llu"

#define SCNuMAX         "llu"
#define SCNuPTR         "u"

#define SCNx8           "hhx"
#define SCNx16          "hx"
#define SCNx32          "x"
#define SCNx64          "llx"

#define SCNxLEAST8      "hhx"
#define SCNxLEAST16     "hx"
#define SCNxLEAST32     "x"
#define SCNxLEAST64     "llx"

#define SCNxFAST8       "hhx"
#define SCNxFAST16      "x"
#define SCNxFAST32      "x"
#define SCNxFAST64      "llx"

#define SCNxMAX         "llx"
#define SCNxPTR         "x"

598.3   Valore assoluto

Nel file stdlib.h si trovano dichiarate alcune funzioni per il calcolo del valore assoluto: ...abs(). Nel file inttypes.h si aggiunge la funzione imaxabs(), da usare per i valori interi massimi:

intmax_t imaxabs (intmax_t j);
#include <inttypes.h>
intmax_t
imaxabs (intmax_t j)
{
    if (j < 0)
      {
        return -j;
      }
    else
      {
        return j;
      }
}    

598.4   Conversione da stringa a numero intero

Per convertire una stringa contenente un valore numerico intero, quando si vuole fare riferimento all'intero di dimensione massima, si possono usare le funzioni strtoimax(), strtouimax(), wcstoimax() e wcstouimax(), dichiarate nel file inttypes.h. Come il nome suggerisce, le prime due funzioni sono destinate alla conversione di stringhe «normali», mentre le altre sono specifiche per le stringhe estese.

Evidentemente si tratta di funzioni che si abbinano alle altre strto...() del file stdlib.h e alle funzioni wcsto...() del file wchar.h.

intmax_t  strtoimax  (const char *restrict nptr,
                      char **restrict endptr, int base);
uintmax_t strtouimax (const char *restrict nptr,
                      char **restrict endptr, int base);
intmax_t wcstoimax   (const wchar_t *restrict nptr,
                      wchar_t **restrict endptr, int base);
uintmax_t wcstouimax (const wchar_t *restrict nptr,
                      wchar_t **restrict endptr, int base);

Come si vede, i parametri delle funzioni sono gli stessi; quello che cambia è il tipo di stringa, che nelle funzioni strto...() è normale, mentre nelle funzioni wcsto...() è di tipo esteso. Nel caso di funzioni ...touimax() si ottiene un valore intero senza segno, mentre con le funzioni ...toimax() si ottiene un valore intero con segno.

Il comportamento di queste funzioni è analogo a quello delle altre funzioni strto...() e wcsto...(), per ciò che riguarda l'interpretazione di valori interi, con la differenza che si fa riferimento al valore intero più grande. Il valore restituito è zero se non si può procedere alla conversione; se invece il valore è al di fuori dell'intervallo rappresentabile, a seconda dei casi si può avere il valore corrispondente a INTMAX_MAX, INTMAX_MIN o UINTMAX_MIN, con l'aggiornamento della variabile errno al valore rappresentato da ERANGE.

598.5   Riferimenti


Appunti di informatica libera 2008 --- Copyright © 2000-2008 Daniele Giacomini -- <appunti2 (ad) gmail·com>


Dovrebbe essere possibile fare riferimento a questa pagina anche con il nome c_171_inttypes_h_187.htm

[successivo] [precedente] [inizio] [fine] [indice generale] [indice ridotto] [indice analitico] [home]

Valid ISO-HTML!

CSS validator!

Gjlg Metamotore e Web Directory