首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> 關於C++

C++ 學習路線圖精華:printf 格式詳解、STL map 實戰與 sizeof 深度解析

     編輯:關於C++

一、printf 格式控制完整指南

格式字串完整語法:%[flags][width][.precision][length]specifier

標誌位

  • -:左對齊(預設右對齊)
  • 0:數值前導補零(預設空格)
  • +:正數顯示 + 號
  • 空格:正數前置空格
  • #:替代形式(八進制前綴 0、十六進制前綴 0x、浮點數強制小數點)

寬度與精度

  • m:最小欄寬,不足補空格/零
  • .n:精度。整數→最小位數;浮點→小數位數;字串→最大字元數
  • *:由參數傳入寬度/精度

長度修飾符

  • hh:char
  • h:short
  • l:long / double / wchar_t*
  • ll:long long
  • L:long double
  • z:size_t
  • t:ptrdiff_t
  • j:intmax_t

轉換指示符速查

指示符含義範例
d, i有號十進制整數%d, %5d, %05d
u無號十進制整數%u
o八進制%o, %#o
x, X十六進制 (小寫/大寫)%x, %#X
f, F十進制浮點數%.2f, %10.4f
e, E科學記號%.3e
g, G自動選 f/e 短者%g
c單一字元%c
s字串%s, %10s, %.5s
p指標位址%p
n已輸出字元數存入指標%n
%輸出 % 字元%%

關鍵提醒

  • float 經預設參數提升為 double,%f 通用;long double 用 %Lf。
  • %lf 在 printf 中等同 %f(C99 標準化);scanf 則必須區分。
  • 輸出 % 必須寫 %%。

二、STL map 實戰完全手冊

基本定義

#include 
#include 
std::map mapStudent;  // 鍵唯一、自動按鍵排序(紅黑樹)

三種插入方式

// 1. pair
mapStudent.insert(std::pair(1, "student_one"));

// 2. value_type
mapStudent.insert(std::map::value_type(2, "student_two"));

// 3. 下標運算子(可覆蓋)
mapStudent[3] = "student_three";

插入成功判斷

auto ret = mapStudent.insert({1, "new"});
if (ret.second)  // true = 成功插入,false = 鍵已存在
    std::cout << "Inserted\n";

遍歷方式

// 正向迭代器
for (auto it = mapStudent.begin(); it != mapStudent.end(); ++it)
    std::cout << it->first << " " << it->second << "\n";

// 反向迭代器
for (auto it = mapStudent.rbegin(); it != mapStudent.rend(); ++it)
    std::cout << it->first << " " << it->second << "\n";

// C++17 結構化綁定
for (auto& [key, val] : mapStudent)
    std::cout << key << " " << val << "\n";

查找與範圍操作

// 單鍵查找
auto it = mapStudent.find(2);
if (it != mapStudent.end()) { /* found */ }

// 計數(map 只能 0 或 1)
size_t cnt = mapStudent.count(2);

// 區間查找
auto range = mapStudent.equal_range(2);  // pair
auto it_low = mapStudent.lower_bound(2); // 首個 ≥ key
auto it_up = mapStudent.upper_bound(2);  // 首個 > key

刪除操作

mapStudent.erase(it);           // 迭代器刪除
mapStudent.erase(2);            // 鍵刪除,回傳刪除數量
mapStudent.erase(begin, end);   // 區間刪除 [begin, end)
mapStudent.clear();             // 全清

自訂排序(鍵為自訂類型)

struct StudentInfo { int id; std::string name; };

// 方法 1:運算子 < 重載
bool operator<(const StudentInfo& a, const StudentInfo& b) {
    return a.id < b.id || (a.id == b.id && a.name < b.name);
}

// 方法 2:仿函數
struct StudentCmp {
    bool operator()(const StudentInfo& a, const StudentInfo& b) const {
        return a.id < b.id || (a.id == b.id && a.name < b.name);
    }
};
std::map mapScore;

效能特性

  • 查找/插入/刪除:O(log n)
  • 節點額外開銷:~16 bytes(父/左右指標 + 紅黑標記)
  • 優於通用 STL 算法:map::find 比 std::find 快(利用樹結構)

三、sizeof 深度解析與常見誤區

sizeof vs strlen

核心規則

  1. 編譯期計算:sizeof 是運算子,非函數,編譯期常數(VLA 除外)。
  2. 類型參數需括號:sizeof(int);變數可省略 sizeof x。
  3. 陣列不退化:sizeof(arr) 為整個陣列大小;傳參退化為指標,函數內 sizeof(ptr) 為指標大小。
  4. 結構體對齊:編譯器插入填充位元組,#pragma pack(n) 控制對齊。
  5. 不完全類型禁用:sizeof(void)、sizeof(外部陣列)、sizeof(位域) 皆非法。

實用場景

  • 動態配置:malloc(sizeof(T) * n)
  • 記憶體操作:memset(buf, 0, sizeof(buf))(僅限陣列非指標)
  • 序列化/網路傳輸:協議頭包含 sizeof(Struct) 利於版本演進
  • 陣列元素計數:sizeof(arr)/sizeof(arr[0])(僅限陣列非指標)
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
表達式sizeofstrlen
char* s = "abc"4/8 (指標大小)3
char s[] = "abc"4 (含 \0)3
char s[100] = "abc"1003
int a[100]400編譯錯誤