Skip to content
LIVE FEED

BlogTổng hợp các dạng printf để in giá trị trong C

Tổng hợp các dạng printf để in giá trị trong C

1. Cú pháp cơ bản

printf("format", value);

Ví dụ:

int x = 10;
printf("%d\n", x);

Kết quả:

10

2. Bảng format specifier cơ bản

Kiểu dữ liệu / mục đíchFormatVí dụ
char%cprintf("%c", c);
int%d / %iprintf("%d", n);
unsigned int%uprintf("%u", n);
long%ldprintf("%ld", n);
unsigned long%luprintf("%lu", n);
long long%lldprintf("%lld", n);
unsigned long long%lluprintf("%llu", n);
float%fprintf("%f", f);
double%fprintf("%f", d);
double dạng khoa học%eprintf("%e", d);
Hex chữ thường%xprintf("%x", n);
Hex chữ hoa%Xprintf("%X", n);
Octal%oprintf("%o", n);
Chuỗi%sprintf("%s", str);
Địa chỉ%pprintf("%p", (void *)ptr);

3. In số nguyên

int

int x = 100;

printf("%d\n", x);

Kết quả:

100

%i cũng có thể dùng cho int:

printf("%i\n", x);

unsigned int

unsigned int x = 100;

printf("%u\n", x);

Kết quả:

100

long

long x = 100000;

printf("%ld\n", x);

long long

long long x = 1234567890123LL;

printf("%lld\n", x);

4. In ký tự

char c = 'A';

printf("%c\n", c);

Kết quả:

A

Có thể in mã ASCII của ký tự:

printf("%d\n", c);

Kết quả:

65

Ví dụ:

char c = 'A';

printf("char = %c\n", c);
printf("decimal = %d\n", c);
printf("hex = 0x%02X\n", c);

Kết quả:

char = A
decimal = 65
hex = 0x41

5. In số thực

float

float x = 3.14f;

printf("%f\n", x);

Kết quả:

3.140000

double

double x = 3.14159265;

printf("%f\n", x);

Giới hạn số chữ số sau dấu chấm

double x = 3.14159265;

printf("%.2f\n", x);

Kết quả:

3.14
printf("%.4f\n", x);

Kết quả:

3.1416

Cú pháp:

%.Nf

Trong đó N là số chữ số muốn hiển thị sau dấu chấm.


6. In Hexadecimal

Đây là phần đặc biệt quan trọng khi làm việc với byte, memory và network packet.

%x — hex chữ thường

int x = 255;

printf("%x\n", x);

Kết quả:

ff

%X — hex chữ hoa

printf("%X\n", x);

Kết quả:

FF

Thêm 0x

printf("0x%x\n", x);

Kết quả:

0xff

Hoặc:

printf("0x%X\n", x);

Kết quả:

0xFF

0x ở đây chỉ là chuỗi ký tự được printf in ra, không phải một format specifier riêng.


7. %02X — cực kỳ hữu ích khi in byte

Ví dụ:

uint8_t x = 5;

printf("%X\n", x);

Kết quả:

5

Nhưng:

printf("%02X\n", x);

Kết quả:

05

Ý nghĩa %02X

% 02 X
│ │  │
│ │  └── Hex chữ hoa
│ └───── độ rộng tối thiểu 2 ký tự
└─────── format

Một số dạng thường gặp:

printf("%02X", x);   // 05
printf("%04X", x);   // 0005
printf("%08X", x);   // 00000005

Ví dụ:

uint8_t x = 0x45;

printf("0x%02X\n", x);

Kết quả:

0x45

8. In uint8_t

uint8_t thường được dùng để biểu diễn một byte.

#include <stdint.h>
#include <stdio.h>

uint8_t x = 0x45;

printf("%u\n", x);
printf("0x%02X\n", x);

Kết quả:

69
0x45

Bởi vì:

0x45 = 4 × 16 + 5
     = 69

9. In một mảng byte

Ví dụ:

#include <stdio.h>
#include <stdint.h>

uint8_t packet[] = {
    0x45,
    0x00,
    0x00,
    0x3C
};

for (int i = 0; i < 4; i++) {
    printf("%02X ", packet[i]);
}

Kết quả:

45 00 00 3C

Nếu muốn có 0x:

for (int i = 0; i < 4; i++) {
    printf("0x%02X ", packet[i]);
}

Kết quả:

0x45 0x00 0x00 0x3C

Đây là cách rất phổ biến để debug raw packet/buffer.


10. In chuỗi

char *str = "Hello";

printf("%s\n", str);

Kết quả:

Hello

11. In địa chỉ bộ nhớ

Dùng %p.

int x = 10;

printf("%p\n", (void *)&x);

Có thể nhận được:

0x7ffd12345670

Địa chỉ thực tế phụ thuộc vào chương trình, hệ điều hành và thời điểm chạy.

Vì sao dùng (void *)?

Cách viết chuẩn:

printf("%p\n", (void *)&x);

%p dùng để in pointer/địa chỉ.


12. array, &array[i] và %p

Ví dụ:

#include <stdio.h>
#include <stdint.h>

uint8_t array[4] = {
    0x45,
    0x00,
    0x00,
    0x3C
};

for (int i = 0; i < 4; i++) {
    printf(
        "array[%d] = 0x%02X, address = %p\n",
        i,
        array[i],
        (void *)&array[i]
    );
}

Có thể cho kết quả:

array[0] = 0x45, address = 0x7ffd12345670
array[1] = 0x00, address = 0x7ffd12345671
array[2] = 0x00, address = 0x7ffd12345672
array[3] = 0x3C, address = 0x7ffd12345673

Vì uint8_t có kích thước 1 byte nên các phần tử liên tiếp cách nhau 1 byte.


13. In pointer

uint8_t array[4] = {0x45, 0x00, 0x00, 0x3C};

uint8_t *ptr = array;

In địa chỉ mà ptr đang trỏ tới

printf("%p\n", (void *)ptr);

In giá trị tại địa chỉ đó

printf("0x%02X\n", *ptr);

Ví dụ:

ptr  → 0x7ffd12345670
*ptr → 0x45

Nhớ:

ptr
 ↓
địa chỉ

*ptr
 ↓
giá trị tại địa chỉ đó

14. Phân biệt ptr, *ptr, &ptr

Ví dụ:

uint8_t x = 0x45;
uint8_t *ptr = &x;

Ta có:

ptr
 ↓
địa chỉ của x

*ptr
 ↓
giá trị của x

&ptr
 ↓
địa chỉ của biến ptr

In:

printf("ptr  = %p\n", (void *)ptr);
printf("*ptr = 0x%02X\n", *ptr);
printf("&ptr = %p\n", (void *)&ptr);

15. Pointer arithmetic và printf

Với:

uint8_t array[4] = {
    0x45,
    0x00,
    0x00,
    0x3C
};

Ta có:

array + 0
array + 1
array + 2
array + 3

là các địa chỉ của:

&array[0]
&array[1]
&array[2]
&array[3]

Có thể kiểm tra bằng:

for (int i = 0; i < 4; i++) {
    printf(
        "i=%d, array+i=%p, &array[i]=%p\n",
        i,
        (void *)(array + i),
        (void *)&array[i]
    );
}

Hai địa chỉ tương ứng sẽ giống nhau.

Công thức quan trọng:

&array[i] == array + i

Và:

array[i] == *(array + i)

16. In giá trị + địa chỉ + index

Đây là mẫu debug rất hữu ích:

for (int i = 0; i < 4; i++) {
    printf(
        "index=%d | value=0x%02X | address=%p\n",
        i,
        array[i],
        (void *)&array[i]
    );
}

Ví dụ:

index=0 | value=0x45 | address=0x7ffd12345670
index=1 | value=0x00 | address=0x7ffd12345671
index=2 | value=0x00 | address=0x7ffd12345672
index=3 | value=0x3C | address=0x7ffd12345673

17. Bảng format nhanh

Muốn inDùng
char%c
int%d
unsigned int%u
long%ld
unsigned long%lu
long long%lld
unsigned long long%llu
float%f
double%f
Hex thường%x
Hex hoa%X
Byte HEX 2 chữ số%02X
HEX 4 chữ số%04X
HEX 8 chữ số%08X
Octal%o
Chuỗi%s
Địa chỉ%p

18. Cheat sheet quan trọng nhất

Nếu đang học C, pointer, memory và network packet thì nhớ các dạng này:

printf("%d", x);                    // int
printf("%u", x);                    // unsigned int

printf("%c", c);                    // char
printf("%s", str);                  // string

printf("%f", f);                    // float/double
printf("%.2f", f);                  // 2 số sau dấu chấm

printf("%x", x);                    // hex thường
printf("%X", x);                    // hex hoa
printf("0x%02X", x);                // byte hex
printf("0x%04X", x);                // 4-digit hex
printf("0x%08X", x);                // 8-digit hex

printf("%p", (void *)ptr);          // địa chỉ

Khi debug packet

printf(
    "index=%d | value=0x%02X | address=%p\n",
    i,
    packet[i],
    (void *)&packet[i]
);

Có thể nhớ đơn giản:

%d       → số nguyên
%u       → số nguyên không dấu
%c       → ký tự
%s       → chuỗi
%f       → số thực
%x / %X  → hex
%02X     → 1 byte dạng HEX
%p       → địa chỉ

Lộ trình học tập

Lập Trình C/C++

  1. 1 01 — C Cơ Bản
  2. 2 02 — Con Trỏ & Bộ Nhớ
  3. 3 03 — Struct, Union, Bitfield & Bố Cục Bộ Nhớ
  4. 4 04 — C Nâng Cao
  5. 5 05 — C++ Cốt Lõi
  6. 6 06 — C++ Hiện Đại
  7. 7 07 — Lập Trình Hệ Thống & Mạng
  8. 8 08 — Phân Tích Giao Thức Telecom Bằng C/C++
  9. 9 09 — An Ninh Bộ Nhớ & Khai Thác Cơ Bản
  10. 10 11 — Lập Trình Nhúng & Real-time (SDR-first)
  11. 11 Bài tập & Pet Project — Lộ trình C/C++ chuyên sâu
  12. 12 Tổng hợp các dạng printf để in giá trị trong C
  13. 13 Bitwise & Mask, Octet, Endian: Hướng dẫn parse protocol byte cho người mới
  14. 14 Tổng hợp: Con trỏ, kích thước kiểu dữ liệu và byte trong bộ nhớ
Contact
Facebook
TOP