Saya memiliki yang berikut ini
size_t i = 0;
uint32_t k = 0;
printf("i [ %lu ] k [ %u ]\n", i, k);
Saya mendapatkan peringatan berikut saat menyusun:
format ‘%lu’ expects type ‘long unsigned int’, but argument has type ‘uint32_t’
Ketika saya menjalankan ini menggunakan belat, saya mendapatkan yang berikut:
Format argument 1 to printf (%u) expects unsigned int gets size_t: k
Terima kasih banyak atas sarannya,
uint32_t
dari<stdint.h>
atau<inttypes.h>
; jika Anda ingin menggunakan tipe tersebut, Anda harus meningkatkan ke C89. Sebagai ekstensi, GCC mungkin mengizinkan Anda untuk menggunakannya, tetapi C89 tidak memiliki dukungan semacam itu.size_t
adalah 'z', seperti pada"%zu"
.uint32_t
, tetapi kurangsize_t
. Jawaban @ u0b34a0f6ae mencakup keduanya.Jawaban:
Kedengarannya seperti Anda mengharapkan
size_t
untuk menjadi sama denganunsigned long
(mungkin 64 bit) padahal sebenarnyaunsigned int
(32 bit). Coba gunakan%zu
dalam kedua kasus.Saya tidak sepenuhnya yakin.
sumber
int32_t
kebetulan adaint
di kompiler / platform Anda tidak berarti itu mungkin tidak adalong
di kompiler lain. Sama untuksize_t
. Ini sebenarnya akan keluar dari jalannya dan melakukan lebih banyak pekerjaan untuk mendeteksi bug portabilitas ini karena pemeriksaan yang mudah dan alami adalah hanya menghormati typedef seperti yang dilakukan kompiler.%lu
bersama-sama(unsigned long)k
selalu benar.size_t
lebih rumit, itulah sebabnya%zu
ditambahkan di C99. Jika Anda tidak dapat menggunakan itu, maka perlakukan seperti ituk
(long
adalah tipe terbesar di C89,size_t
sangat tidak mungkin lebih besar).Mencoba
The
z
mewakili bilangan bulat panjang yang sama sepertisize_t
, danPRIu32
makro, didefinisikan dalam header C99inttypes.h
, merupakan 32-bit unsigned integer.sumber
printf( "%lu", (unsigned long )i )
. Jika tidak, seseorang akan berakhir dengan tumpukan peringatan di seluruh kode karena perubahan jenis.uint32_t
jadi sebenarnya itu adalah kode C99, dan harus dikompilasi seperti itu.Yang diperlukan hanyalah penentu format dan jenisnya setuju, dan Anda selalu dapat melakukan transmisi untuk membuatnya benar.
long
setidaknya 32 bit, jadi%lu
bersama-sama dengan(unsigned long)k
selalu benar:size_t
lebih rumit, itulah sebabnya%zu
ditambahkan di C99. Jika Anda tidak dapat menggunakan itu, maka perlakukan seperti ituk
(long
adalah tipe terbesar di C89,size_t
sangat tidak mungkin lebih besar).Jika Anda tidak mendapatkan penentu format yang benar untuk tipe yang Anda lewati, maka
printf
akan melakukan hal yang sama dengan membaca terlalu banyak atau terlalu sedikit memori yang keluar dari larik. Selama Anda menggunakan cast eksplisit untuk mencocokkan tipe, ini portabel.sumber
Jika Anda tidak ingin menggunakan makro PRI *, pendekatan lain untuk mencetak jenis bilangan bulat APA PUN adalah dengan mentransmisikan ke
intmax_t
atauuintmax_t
dan menggunakan"%jd"
atau%ju
, masing-masing. Ini sangat berguna untuk jenis POSIX (atau OS lain) yang tidak memiliki makro PRI * yang ditentukan, misalnyaoff_t
.sumber