C&C++快速入门

3、第一个C&C++程序

1. 课程目标

本课时将学习:

  • 理解C/C++程序的基本结构
  • main函数的作用
  • 预处理指令与头文件
  • 编写并运行第一个程序

2. C语言Hello World

2.1 源代码

// hello.c
#include <stdio.h>  // 预处理指令:包含标准输入输出库

// main函数:程序入口点
int main() {
    // 输出字符串到控制台
    printf("Hello, World!\n");
    
    // 返回0表示程序正常结束
    return 0;
}

2.2 代码解析

代码元素 说明
#include <stdio.h> 预处理指令,包含标准I/O库
int main() 主函数,程序执行的入口
printf() 格式化输出函数
\n 转义字符,换行
return 0 返回值,0表示成功

2.3 编译运行

# Windows (MinGW)
gcc hello.c -o hello.exe
.\hello.exe

# Linux
gcc hello.c -o hello
./hello

3. C++语言Hello World

3.1 源代码

// hello.cpp
#include <iostream>  // C++标准输入输出流

using namespace std;  // 使用标准命名空间

int main() {
    cout << "Hello, C++!" << endl;  // 输出并换行
    return 0;
}

3.2 C++ vs C对比

特性 C语言 C++
头文件 <stdio.h> <iostream>
输出 printf() cout <<
输入 scanf() cin >>
换行 \n endl
命名空间 namespace

3.3 编译运行

# Windows
g++ hello.cpp -o hello.exe
.\hello.exe

# Linux
g++ hello.cpp -o hello
./hello

4. 程序结构详解

4.1 预处理指令

// 包含系统头文件(尖括号)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// 包含自定义头文件(双引号)
#include "myheader.h"

// 宏定义
#define MAX_SIZE 1024
#define PI 3.14159

// 条件编译
#ifdef _WIN32
    #include <windows.h>
#else
    #include <unistd.h>
#endif

4.2 main函数的参数

// 无参数版本
int main() {
    return 0;
}

// 带参数版本(处理命令行参数)
int main(int argc, char *argv[]) {
    // argc: 参数数量
    // argv: 参数数组
    
    printf("程序名: %s\n", argv[0]);
    printf("参数数量: %d\n", argc);
    
    for (int i = 1; i < argc; i++) {
        printf("参数%d: %s\n", i, argv[i]);
    }
    
    return 0;
}

运行示例:

./program arg1 arg2 arg3
# 输出:
# 程序名: ./program
# 参数数量: 4
# 参数1: arg1
# 参数2: arg2
# 参数3: arg3

4.3 返回值的意义

int main() {
    // 返回值会传递给操作系统
    // 0: 成功
    // 非0: 失败(不同的值代表不同错误)
    
    return 0;  // 成功
    // return 1;  // 一般错误
    // return -1; // 严重错误
}

检查返回值:

# Linux
./program
echo $?  # 输出返回值

# Windows PowerShell
.\program.exe
$LASTEXITCODE

5. 注释规范

5.1 C语言注释

// 单行注释(C99起支持)

/* 
   多行注释
   可以跨越多行
*/

/*
 * 常见的函数注释风格
 * @brief 函数功能说明
 * @param param1 参数说明
 * @return 返回值说明
 */

5.2 C++注释

// C++同样支持两种注释

/// 三条斜线用于Doxygen文档生成

/**
 * @class MyClass
 * @brief 类的说明
 */

6. 安全开发第一个程序

6.1 程序信息收集示例

// sysinfo.c - 系统信息收集程序
#include <stdio.h>
#include <stdlib.h>

#ifdef _WIN32
    #include <windows.h>
#else
    #include <unistd.h>
    #include <sys/utsname.h>
#endif

int main() {
    printf("========== System Information ==========\n");
    
#ifdef _WIN32
    // Windows系统信息
    char computerName[256];
    DWORD size = sizeof(computerName);
    GetComputerNameA(computerName, &size);
    printf("[*] Computer Name: %s\n", computerName);
    
    char userName[256];
    size = sizeof(userName);
    GetUserNameA(userName, &size);
    printf("[*] User Name: %s\n", userName);
    
    OSVERSIONINFOA osvi;
    osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOA);
    printf("[*] Platform: Windows\n");
    printf("[*] Process ID: %lu\n", GetCurrentProcessId());
    
#else
    // Linux系统信息
    struct utsname info;
    uname(&info);
    
    printf("[*] System: %s\n", info.sysname);
    printf("[*] Hostname: %s\n", info.nodename);
    printf("[*] Release: %s\n", info.release);
    printf("[*] Architecture: %s\n", info.machine);
    printf("[*] PID: %d\n", getpid());
    printf("[*] UID: %d\n", getuid());
    
#endif

    printf("=========================================\n");
    return 0;
}

6.2 跨平台编译

# Windows
gcc sysinfo.c -o sysinfo.exe

# Linux
gcc sysinfo.c -o sysinfo

7. C++版本程序

// sysinfo.cpp
#include <iostream>
#include <string>

#ifdef _WIN32
    #include <windows.h>
#else
    #include <unistd.h>
    #include <sys/utsname.h>
#endif

using namespace std;

int main() {
    cout << "========== System Information (C++) ==========" << endl;
    
#ifdef _WIN32
    char computerName[256];
    DWORD size = sizeof(computerName);
    GetComputerNameA(computerName, &size);
    cout << "[*] Computer: " << computerName << endl;
    
    char userName[256];
    size = sizeof(userName);
    GetUserNameA(userName, &size);
    cout << "[*] User: " << userName << endl;
    cout << "[*] PID: " << GetCurrentProcessId() << endl;
    
#else
    struct utsname info;
    uname(&info);
    
    cout << "[*] System: " << info.sysname << endl;
    cout << "[*] Host: " << info.nodename << endl;
    cout << "[*] Kernel: " << info.release << endl;
    cout << "[*] Arch: " << info.machine << endl;
    cout << "[*] PID: " << getpid() << endl;
    
#endif
    
    cout << "==============================================" << endl;
    return 0;
}

8. 调试技巧

8.1 使用printf调试

#include <stdio.h>

// 定义调试宏
#ifdef DEBUG
    #define DEBUG_PRINT(fmt, ...) \
        printf("[DEBUG] %s:%d " fmt "\n", __FILE__, __LINE__, ##__VA_ARGS__)
#else
    #define DEBUG_PRINT(fmt, ...) // 空定义
#endif

int main() {
    int value = 42;
    
    DEBUG_PRINT("程序开始");
    DEBUG_PRINT("value = %d", value);
    
    // 正常代码...
    
    DEBUG_PRINT("程序结束");
    return 0;
}

编译:

# 开启调试
gcc -DDEBUG main.c -o main

# 关闭调试
gcc main.c -o main

8.2 断言

#include <stdio.h>
#include <assert.h>

int main() {
    int *ptr = NULL;
    
    // 断言:如果条件为假,程序终止
    assert(ptr != NULL);  // 这里会触发断言失败
    
    printf("不会执行到这里\n");
    return 0;
}

9. 编码规范

9.1 命名规范

// 变量命名:小写字母,下划线分隔
int user_count;
char *file_name;

// 常量命名:大写字母
#define MAX_BUFFER_SIZE 1024
const int MAX_RETRY_COUNT = 3;

// 函数命名:动词开头,驼峰或下划线
void initSystem();
int get_user_input();

// 结构体/类命名:首字母大写
typedef struct UserInfo {
    char name[64];
    int age;
} UserInfo;

9.2 代码格式

// 推荐的代码风格
if (condition) {
    // 左花括号不换行
    doSomething();
} else {
    doOtherThing();
}

// 函数定义
int calculateSum(int a, int b) {
    return a + b;
}

// 避免过长的行
printf("This is a very long message that "
       "should be split into multiple lines "
       "for better readability\n");

10. 课后练习

  1. 编写程序输出你的名字和学习目标
  2. 编写程序接受命令行参数并输出
  3. 编写跨平台程序显示当前进程ID
  4. 创建带DEBUG宏的程序,练习调试输出

11. 下一课预告

下一课我们将学习进制与位的概念,这是理解计算机底层的基础。