Swap Two Pointers Using Double Pointers

Code

#include <stdio.h>

// Hàm hoán đổi 2 con trỏ sử dụng con trỏ kép
void swap_pointers(int **p1, int **p2) {
    // Hoán đổi địa chỉ mà p1 và p2 đang lưu
    int *temp = *p1;  // Lưu địa chỉ mà p1 đang trỏ
    *p1 = *p2;        // p1 trỏ sang nơi p2 đang trỏ
    *p2 = temp;       // p2 trỏ sang nơi p1 ban đầu trỏ
}

int main() {
    int a, b;
    scanf("%d %d", &a, &b);
    
    int *p1 = &a;  // p1 trỏ vào a
    int *p2 = &b;  // p2 trỏ vào b
    
    swap_pointers(&p1, &p2);  // Truyền địa chỉ của p1 và p2
    
    printf("%d %d", *p1, *p2);
    
    return 0;
}

/*
 * ═══════════════════════════════════════════════════════════
 * GIẢI THÍCH CHI TIẾT - SWAP TWO POINTERS
 * ═══════════════════════════════════════════════════════════
 * 
 * ĐIỂM QUAN TRỌNG:
 * - Bài này KHÔNG hoán đổi giá trị a, b
 * - Bài này hoán đổi ĐỊA CHỈ mà p1, p2 đang lưu
 * 
 * ═══════════════════════════════════════════════════════════
 * TRACE EXAMPLE 1: a = 10, b = 20
 * ═══════════════════════════════════════════════════════════
 * 
 * TRƯỚC KHI SWAP:
 * ───────────────
 * Memory Layout:
 * 
 *    ┌─────────┬──────────┐
 *    │    a    │    10    │  ← Tại địa chỉ 0x100
 *    └─────────┴──────────┘
 * 
 *    ┌─────────┬──────────┐
 *    │    b    │    20    │  ← Tại địa chỉ 0x150
 *    └─────────┴──────────┘
 * 
 *    ┌─────────┬──────────┐
 *    │   p1    │  0x100   │  ← p1 trỏ vào a
 *    └─────────┴──────────┘
 * 
 *    ┌─────────┬──────────┐
 *    │   p2    │  0x150   │  ← p2 trỏ vào b
 *    └─────────┴──────────┘
 * 
 * Kiểm tra:
 *   *p1 = 10 (giá trị tại 0x100)
 *   *p2 = 20 (giá trị tại 0x150)
 * 
 * 
 * TRONG HÀM swap_pointers(&p1, &p2):
 * ───────────────────────────────────
 * 
 * Tham số nhận được:
 *   **p1 = địa chỉ của p1 (ví dụ: 0x200)
 *   **p2 = địa chỉ của p2 (ví dụ: 0x250)
 * 
 * Bước 1: int *temp = *p1;
 *   *p1 = 0x100 (địa chỉ mà p1 đang lưu)
 *   temp = 0x100
 * 
 * Bước 2: *p1 = *p2;
 *   *p2 = 0x150 (địa chỉ mà p2 đang lưu)
 *   *p1 = 0x150
 *   → p1 BÂY GIỜ TRỎ VÀO b!
 * 
 * Bước 3: *p2 = temp;
 *   temp = 0x100
 *   *p2 = 0x100
 *   → p2 BÂY GIỜ TRỎ VÀO a!
 * 
 * 
 * SAU KHI SWAP:
 * ─────────────
 * 
 *    ┌─────────┬──────────┐
 *    │    a    │    10    │  ← Vẫn tại 0x100 (KHÔNG ĐỔI)
 *    └─────────┴──────────┘
 * 
 *    ┌─────────┬──────────┐
 *    │    b    │    20    │  ← Vẫn tại 0x150 (KHÔNG ĐỔI)
 *    └─────────┴──────────┘
 * 
 *    ┌─────────┬──────────┐
 *    │   p1    │  0x150   │  ← p1 BÂY GIỜ TRỎ VÀO b ✓
 *    └─────────┴──────────┘
 * 
 *    ┌─────────┬──────────┐
 *    │   p2    │  0x100   │  ← p2 BÂY GIỜ TRỎ VÀO a ✓
 *    └─────────┴──────────┘
 * 
 * Kiểm tra:
 *   *p1 = 20 (bây giờ p1 trỏ vào b)
 *   *p2 = 10 (bây giờ p2 trỏ vào a)
 * 
 * Output: a points to 20, b points to 10 ✓
 * 
 * 
 * ═══════════════════════════════════════════════════════════
 * TRACE EXAMPLE 2: a = 5, b = 15
 * ═══════════════════════════════════════════════════════════
 * 
 * TRƯỚC: p1 → a(5), p2 → b(15)
 * 
 * TRONG HÀM:
 *   temp = *p1 = địa chỉ của a
 *   *p1 = *p2 = địa chỉ của b  → p1 trỏ vào b
 *   *p2 = temp = địa chỉ của a → p2 trỏ vào a
 * 
 * SAU: p1 → b(15), p2 → a(5)
 * 
 * Output: a points to 15, b points to 5 ✓
 * 
 * 
 * ═══════════════════════════════════════════════════════════
 * SO SÁNH: SWAP GIÁ TRỊ vs SWAP CON TRỎ
 * ═══════════════════════════════════════════════════════════
 * 
 * ┌──────────────────────┬─────────────────┬─────────────────┐
 * │                      │  Swap giá trị   │  Swap con trỏ   │
 * ├──────────────────────┼─────────────────┼─────────────────┤
 * │ Hàm                  │ swap(int*, int*)│ swap(**p1, **p2)│
 * │ Thay đổi             │ Giá trị a, b    │ Địa chỉ p1, p2  │
 * │ a, b sau khi swap    │ THAY ĐỔI        │ KHÔNG ĐỔI       │
 * │ p1, p2 sau khi swap  │ KHÔNG ĐỔI       │ THAY ĐỔI        │
 * └──────────────────────┴─────────────────┴─────────────────┘
 * 
 * Ví dụ cụ thể với a=10, b=20:
 * 
 * SWAP GIÁ TRỊ:
 *   Trước: a=10, b=20, p1→a, p2→b
 *   Sau:   a=20, b=10, p1→a, p2→b
 *   *p1 = 20, *p2 = 10
 * 
 * SWAP CON TRỎ (bài này):
 *   Trước: a=10, b=20, p1→a, p2→b
 *   Sau:   a=10, b=20, p1→b, p2→a
 *   *p1 = 20, *p2 = 10
 * 
 * ═══════════════════════════════════════════════════════════
 * TẠI SAO CẦN CON TRỎ KÉP?
 * ═══════════════════════════════════════════════════════════
 * 
 * ❌ SAI: void swap_pointers(int *p1, int *p2)
 * 
 *   → Hàm chỉ nhận BẢN SAO của p1, p2
 *   → Thay đổi trong hàm KHÔNG ảnh hưởng p1, p2 gốc
 *   → Sau khi return, p1, p2 vẫn trỏ chỗ cũ!
 * 
 * ✓ ĐÚNG: void swap_pointers(int **p1, int **p2)
 * 
 *   → Hàm nhận ĐỊA CHỈ của p1, p2
 *   → Có thể thay đổi CHÍNH p1, p2 gốc
 *   → Sau khi return, p1, p2 đã trỏ chỗ mới!
 * 
 * ═══════════════════════════════════════════════════════════
 * TÓM TẮT CÔNG THỨC:
 * ═══════════════════════════════════════════════════════════
 * 
 * Muốn thay đổi gì    → Phải truyền địa chỉ của cái đó
 * 
 * - Thay đổi giá trị int     → truyền int*
 * - Thay đổi con trỏ int*    → truyền int**
 * - Thay đổi con trỏ int**   → truyền int*** (hiếm dùng)
 */

Solving Approach

 

 

 

Upvote
Downvote
Loading...

Input

10 20

Expected Output

20 10