Motiviation
帮一位同学开始系统地学计算机, 考虑到CS61A/B/C路线对英文和找资料有比较高的要求, 遂为其转进国内优秀课程路线. 为了能够使用上配套的OJ, 先搞定一下C语言mac开发环境.
入门这块OJ很重要,毕竟, 想成为一名好程序员, 编程这门手艺活还是得6啊.
总体步骤
- 安装XCode
- VS Code 安装插件
C/C++ Extension Pack
Code Runner
- 新建项目
mkdir learning-c-programming && cd learning-c-programming && mkdir {.vscode,build}
- 使用VS Code打开目录, 新建以下文件
tasks.json
# 用于编译c++文件launch.json
# 用于使用vscode自带的debug工具(左侧的小虫图标)c_cpp_properties.json
# 用于使用vscode自带的代码提示工具如 IntelliSensesettings.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"
}
}
使用说明
- 针对OJ, 所以认为单个c文件即为完整程序。
- 在打开的
foo.c
文件tab中通过Command + Shift + B
编译文件, 产物会生成在build/foo
, 可通过cd build && ./foo
来运行. - 处理标准输入流建议使用fscanf, 做一个环境开关(可见最后的样例代码), 相关知识可见
- 本文写作时还看到了挺不错的复习参考, 初学者请先跳过
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