Skip to main content

One post tagged with "mac"

View All Tags

· 6 min read
aweffr

Motiviation

帮一位同学开始系统地学计算机, 考虑到CS61A/B/C路线对英文和找资料有比较高的要求, 遂为其转进国内优秀课程路线. 为了能够使用上配套的OJ, 先搞定一下C语言mac开发环境.

入门这块OJ很重要,毕竟, 想成为一名好程序员, 编程这门手艺活还是得6啊.

总体步骤

  1. 安装XCode
  2. VS Code 安装插件
    1. C/C++ Extension Pack
    2. Code Runner
  3. 新建项目
    1. mkdir learning-c-programming && cd learning-c-programming && mkdir {.vscode,build}
  4. 使用VS Code打开目录, 新建以下文件
    1. tasks.json # 用于编译c++文件
    2. launch.json # 用于使用vscode自带的debug工具(左侧的小虫图标)
    3. c_cpp_properties.json # 用于使用vscode自带的代码提示工具如 IntelliSense
    4. settings.json # 添加 Code Runner 相关配置

Workspace 配置文件

配置 tasks.json

快捷键 Command+Shift+B, vscode会执行tasks.json中的任务.

文件内容如下:

{
"version": "2.0.0",
"tasks": [
{
"label": "C/C++: clang++ 生成活动文件",
"type": "shell",
"command": "clang",
"args": [
"-Wall",
"-Wno-unused-variable",
"-std=c++17",
"-g",
"${file}",
"-o",
"${workspaceFolder}/build/${fileBasenameNoExtension}"
],
"options": {
"cwd": "${workspaceFolder}"
},
"problemMatcher": [
"$gcc"
],
"group": "build"
}
]
}

配置 c_cpp_properties.json

c_cpp_properties.json 的作用是:代码提示、代码跳转等

{
"configurations": [
{
"name": "Mac",
"includePath": [
"${workspaceFolder}/**",
"/Library/Developer/CommandLineTools/usr/include",
// 注意, clang的include文件位置需要根据实际安装结果修改
"/Library/Developer/CommandLineTools/usr/lib/clang/12.0.5/include",
"/usr/local/include"
],
"defines": [],
"macFrameworkPath": [
"/System/Library/Frameworks",
"/Library/Frameworks"
],
"compilerPath": "/usr/bin/clang++",
"cStandard": "c11",
"cppStandard": "c++17",
"intelliSenseMode": "clang-x64"
}
],
"version": 4
}

配置 launch.json

launch.json是调用vscode debug功能的配置文件

{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "clang++ - 生成和调试活动文件",
"type": "cppdbg",
"request": "launch",
"program": "${workspaceFolder}/build/${fileBasenameNoExtension}",
"args": [
"args", "can", "be", "there"
],
"stopAtEntry": false,
"cwd": "${workspaceFolder}/build",
"environment": [],
"externalConsole": false,
"MIMode": "lldb",
"preLaunchTask": "C/C++: clang++ 生成活动文件"
}
]
}

配置 settings.json

配置 Code Runner 来快捷执行代码。

  • Control+Option+N 编译并执行代码
  • Control+Option+M 终止执行
{
"files.associations": {
"__bit_reference": "c",
"__string": "c",
"cstring": "c",
"cstdio": "c"
},
"code-runner.executorMap": {
"c": "cd $dir && clang -Wall -Wno-unused-variable -Wno-implicit-function-declaration -std=c11 $fileName -o $workspaceRoot/build/$fileNameWithoutExt && cd $workspaceRoot/build && ./$fileNameWithoutExt",
"cpp": "cd $dir && clang++ -Wall -Wno-unused-variable -Wno-implicit-function-declaration -std=c++17 $fileName -o $workspaceRoot/build/$fileNameWithoutExt && cd $workspaceRoot/build && ./$fileNameWithoutExt"
}
}

使用说明

c程序示例 处理输入

/**
* @file bubble-sort.cpp
* @author aweffr (aweffr@foxmail.com)
* @brief 提交OJ模板, 演示: 1. 读数组数据 2. 按环境区分如何处理输入
* @version 0.1
* @date 2022-03-12
*/
#include <cstdio>
#include <cstdlib>
#include <cstring>

#define MAX_INPUT_SIZE 50000

#define __DEV__ 0
#define __DEV_FILE__ "/Users/aweffr/Developer/learning-c-programming/problem-set1/input.txt"

void swap(int *arr, int i, int j);

/**
* @brief 根据 __DEV__ 决定是从编写的测试input文件还是OJ的stdin读取输入
*
* @return FILE*
*/
FILE *get_input()
{
FILE *fptr = stdin;
if (__DEV__)
{
printf("[DEBUG]Reading input from %s ...\n", __DEV_FILE__);
fptr = fopen(__DEV_FILE__, "r");
if (fptr == NULL)
{
printf("Open File Error!");
exit(1);
}
}
return fptr;
}

int main(int argc, char *argv[])
{
int N = 0;

FILE *fptr = get_input();

fscanf(fptr, "%d\n", &N);

int input_arr[MAX_INPUT_SIZE];
memset(input_arr, 0, MAX_INPUT_SIZE);

for (int i = 0; i < N; i++)
{
fscanf(fptr, "%d\n", &input_arr[i]);
}

for (int i = 0; i < N; i++)
{
for (int j = 0; j < N - 1; j++)
{
if (input_arr[j] > input_arr[j + 1])
{
swap(input_arr, j, j + 1);
}
}
}

printf("sorted result: ");
for (int i = 0; i < N; i++)
{
const char *fmt = (i == 0) ? " %d" : ", %d";
printf(fmt, input_arr[i]);
}
printf("\n");

return 0;
}

void swap(int *arr, int i, int j)
{
int tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}

Code Runner 执行效果:

[Running] cd "/Users/aweffr/Developer/learning-c-programming/problem-set1/" && clang++ -Wall -Wno-unused-variable -Wno-implicit-function-declaration -std=c++17 bubble-sort.cpp -o /Users/aweffr/Developer/learning-c-programming/build/bubble-sort && cd /Users/aweffr/Developer/learning-c-programming/build && ./bubble-sort
[DEBUG]Reading input from /Users/aweffr/Developer/learning-c-programming/problem-set1/input.txt ...
sorted result: 1, 2, 3, 4, 8, 11, 111, 123, 12312, 12313

[Done] exited with code=0 in 2.958 seconds

参考文档

  1. segmentfault: mac vscode c++ 环境配置及异常的语法提示
  2. VS Code 官方文档: Using Clang in Visual Studio Code
  3. VS Code变量参考手册
  4. Clang 命令行手册
  5. CMU 15-123 C & Unix S11
  6. CMU 15-123 C & Unix N09