_countof _crt_countof宏

本文详细解析了_crt_countof宏在C++中的定义和工作原理,通过示例和C++ Primer的解释,阐述了如何利用模板和 sizeof 操作符来确定数组的大小,并指出在使用中的注意事项。

stdlib.h

#ifndef _countof
    #define _countof __crt_countof
#endif

vcryntime.h

#ifdef __cplusplus
    extern "C++"
    {
   
   
        template <typename _CountofType, size_t _SizeOfArray>
        char (*__countof_helper(_UNALIGNED _CountofType (&_Array)[_SizeOfArray]))[_SizeOfArray];

        #define __crt_countof(_Array) (sizeof(*__countof_helper(_Array)) + 0)
    }
#define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <conio.h> // 提供 _kbhit() 和 _getch() #include <windows.h> // 提供 Sleep() // 菜单项结构体 typedef struct { char name[10]; } MenuItem; #define FIRST_MENU_COUNT 3 #define SECOND_MENU_COUNT 3 MenuItem firstMenus[FIRST_MENU_COUNT] = { {"A"}, {"B"}, {"C"} }; MenuItem secondMenus[FIRST_MENU_COUNT][SECOND_MENU_COUNT] = { {{"A1"}, {"A2"}, {"A3"}}, {{"B1"}, {"B2"}, {"B3"}}, {{"C1"}, {"C2"}, {"C3"}} }; int currentFirstIndex = 0; // 当前选中的主菜单索引 int currentSecondIndex = 0; // 当前选中的子菜单索引 // 打印菜单 void PrintMenu() { system("cls"); // 清屏(Windows 系统) // 打印一级菜单 printf("【一级菜单】\n"); for (int i = 0; i < FIRST_MENU_COUNT; i++) { if (i == currentFirstIndex) printf("[ %s ] ", firstMenus[i].name); else printf(" %s ", firstMenus[i].name); } printf("\n\n"); // 打印二级菜单 printf("【二级菜单】\n"); for (int i = 0; i < SECOND_MENU_COUNT; i++) { if (i == currentSecondIndex) printf("[ %s ]\n", secondMenus[currentFirstIndex][i].name); else printf(" %s \n", secondMenus[currentFirstIndex][i].name); } printf("\n按 Esc 退出程序。\n"); } // 主函数 int main() { while (1) { PrintMenu(); if (_kbhit()) { // 检测是否有按键按下 int key = _getch(); // 获取按键值 switch (key) { case 75: // 左箭头 ← if (currentFirstIndex > 0) currentFirstIndex--; break; case 77: // 右箭头 → if (currentFirstIndex < FIRST_MENU_COUNT - 1) currentFirstIndex++; break; case 72: // 上箭头 ↑ if (currentSecondIndex > 0) currentSecondIndex--; break; case 80: // 下箭头 ↓ if (currentSecondIndex < SECOND_MENU_COUNT - 1) currentSecondIndex++; break; case 27: // Esc 键 printf("程序已退出。\n"); exit(0); default: break; } } Sleep(100); // 控制刷新频率,避免卡顿 } return 0; } 输出和注释改成英文
10-17
#define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <conio.h> // Provides _kbhit() and _getch() #include <windows.h> // Provides Sleep() // Define custom type typedef unsigned char U1; // Constants to replace magic numbers #define FALSE (U1)0 #define TRUE (U1)1 #define LEFT_ARROW 75 #define RIGHT_ARROW 77 #define UP_ARROW 72 #define DOWN_ARROW 80 #define ESC_KEY 27 #define U1_TEN 10 #define SLEEPTIME 100 // Menu item structure typedef struct { char name[U1_TEN]; } MenuItem; #define FIRST_MENU_COUNT 3 #define SECOND_MENU_COUNT 3 MenuItem firstMenus[FIRST_MENU_COUNT] = { {"A"}, {"B"}, {"C"} }; MenuItem secondMenus[FIRST_MENU_COUNT][SECOND_MENU_COUNT] = { {{"A1"}, {"A2"}, {"A3"}}, {{"B1"}, {"B2"}, {"B3"}}, {{"C1"}, {"C2"}, {"C3"}} }; U1 currentFirstIndex = FALSE; // Index of currently selected main menu U1 currentSecondIndex = FALSE; // Index of currently selected sub-menu // Function to print the menu void PrintMenu() { system("cls"); // Clear screen (Windows only) // Print the main menu printf("[ Main Menu ]\n"); for (U1 i = FALSE; i < FIRST_MENU_COUNT; i++) { if (i == currentFirstIndex) printf("[ %s ] ", firstMenus[i].name); else printf(" %s ", firstMenus[i].name); } printf("\n\n"); // Print the sub-menu printf("[ Sub-Menu ]\n"); for (U1 i = FALSE; i < SECOND_MENU_COUNT; i++) { if (i == currentSecondIndex) printf("[ %s ]\n", secondMenus[currentFirstIndex][i].name); else printf(" %s \n", secondMenus[currentFirstIndex][i].name); } printf("\nPress Esc to exit the program.\n"); } // Main function void main() { while (TRUE) { PrintMenu(); if (_kbhit()) { // Check if a key is pressed int key = _getch(); // Get the key value switch (key) { case LEFT_ARROW: // Left arrow ← if (currentFirstIndex > FALSE) currentFirstIndex--; break; case RIGHT_ARROW: // Right arrow → if (currentFirstIndex < (FIRST_MENU_COUNT - TRUE)) currentFirstIndex++; break; case UP_ARROW: // Up arrow ↑ if (currentSecondIndex > FALSE) currentSecondIndex--; break; case DOWN_ARROW: // Down arrow ↓ if (currentSecondIndex < (SECOND_MENU_COUNT - TRUE)) currentSecondIndex++; break; case ESC_KEY: // Esc key printf("Program exited.\n"); exit(FALSE); default: break; } } Sleep(SLEEPTIME); // Control refresh rate to avoid flickering } } 加点注释
最新发布
10-17
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值