Tools#

In the following I list the steps to setup an environment based on VSCodium β€” the open-source version of the popular text editor Visual Studio Code (VS Code). The following instructions should also work with VS Code, though if you have it already. Just be aware that VS Code sends usage data as default that not everyone may be comfortable with, but it can be turned off in many cases.

A text editor is not enough to create programs executable by our computer. Along with the text editor we will install additional tools like compiler, language server etc.

For the following tutorial I used a computer with an Intel x86-64 bit processor with Windows 11 OS build 26100 (refer to System Information). Even I tried to cater for other processors and OSs, I could not test the steps on other hardware/OS, which I don’t have access to. If the following steps do not work out for you, we can find a solution in the class. If you miss something in the steps or found an error, please create an issue or a pull request to help other students.

Installation of VSCodium#

We will use a package manager. For Windows: VSCodium is not available on Microsoft Store unlike VS Code.

  1. Open a command prompt on your OS, e.g., using ⊞ Win, then typing cmd on Windows.

  2. Use your package manager’s install command, e.g., winget on Windows:

    winget install vscodium
    

    For other package managers, refer to these instructions.

If you have problems with your package manager then you can try manual installation as a last resort. Bear in mind that we will use the package manager to install further software, so better make it run πŸ™‚.

Customizing the editor#

  1. When you run for the first time, you should see a walkthrough for getting started.

  2. First pick a theme that fits your environment and your taste. A study found out that a light theme is best in a well-lit environment during the day, and dark during the night.

    I like Solarized Light, because complete white strains my eyes. You can find it when you click on Browse Color Themes button or See more themes.

    After choosing your theme you should see a βœ… beside Choose your theme.

  3. We will leave the walkthrough without visiting other steps. We will setup other tools when we need them to understand why we need them. Click on Go Back on the top left corner of the tab to discard the walkthrough window. You should see the Welcome tab.

Creating and opening a new folder#

Now we will write our first program. For each program we will code, we will use a single folder. During the semester you will write also many other programs. So think about where you will place your folder.

Tip

My recommended directory structure is:

πŸ“ your-home-folder
β”œβ”€β”€ πŸ“ uni
    β”œβ”€β”€ πŸ“ 25WS
        β”œβ”€β”€ πŸ“ cprog
            β”œβ”€β”€ πŸ“ code
                β”œβ”€β”€ πŸ“ hello
                β”œβ”€β”€ πŸ“ guess-the-number
                β”œβ”€β”€ πŸ“ ...

hello and guess-the-number are individual C projects.

Now we will create the folder hello for our first program.

  1. On the EXPLORER tab, click on Open Folder. You should see your file explorer.

  2. Create the folder structure that you like as we discussed before and then hello.

  3. In the file explorer, click on hello and then Select folder. A new window should pop-up with the title Do you trust the authors of the files in this folder?.

  4. We will not run code or tasks associated with this code that originate from authors we do not trust. We can trust the folder.

    Tick the box for Trust the authors of all files in the parent folder 'code' and click on Yes .... You should see your folder open but empty on the EXPLORER tab on the left.

  5. Hover with your mouse on the EXPLORER tab on the left. You will see multiple icons.

  6. Click on New File.... A file name prompt will be activated.

  7. Enter main.c. In C, the root source file is named main.c by convention. Why? You will understand in the next steps. After the prompt main.c will be opened in a new tab.

  8. One of the most basic things we can do with a program is to output some characters to us β€” this is a way of communication between the program and us. Let us do that. Write the following code by hand to get the feeling of different symbols used in C language syntax.

    Tip

    Consider using the US keyboard layout for programming. Many symbols like #, <, [, ;, : are easier to access.

    int main() {return 42;}
    
  9. Before you save, pay attention to the main.c in the tab’s title. You should see a full circle similar to ⚫. This means that the file is not saved. Now save it using Ctrls. The circle should turn to a cross mark similar to ❎.

We have written code to control the behavior of a computer. This is called source code.

source code

a plain text computer program written in a programming language

Starting a program using the terminal#

Let us try to execute our code. We usually start programs by double-clicking on them in the file explorer. We will use another approach β€” using the terminal.

  1. Press CtrlShift`. A new window should open in the bottom of the editor with TERMINAL activated.

    On Windows it should show something similar to:

    PS C:\Users\user\...\hello>
    
  2. To execute it, write:

    • on Windows: .\main.c

    • on Linux, macOS: ./main.c

    and press Enter. What happened? Did you see any output, e.g., 1?

    • on Windows: You will probably see that the operating system focus changes again to the editor tab with main.c β€” the same behavior that you would expect when you double-click on the file.

    • on Linux, macOS: You will probably see an error message that you don’t have the permission to execute the file.

Remember that main.c is a source code and is in a human-readable format. It is not meant to be executed by the computer. Computer only understands machine code, so we have to translate our code first.

machine code

code consisting of machine language instructions

Why did we use a rather primitive way of starting our program? Reason: In this course we will focus on programs that input and output data using terminal, which is easier to program.

skinparam packageStyle rect

package "Text terminal" #DDDDDD {
    rectangle keyboard as K
    rectangle display as D
}

rectangle program as P

' Layout positioning
K -[hidden]down-> P
D -[hidden]down-> P

K -> P : input
P -> D : output

text terminal

a serial computer interface for text entry and display

Installing a compiler#

Remember that we have to translate our source code to machine code, to do this, we need to install a compiler.

compiler

a computer program that translates computer code written in one language into another language

We will use clang compiler which is part of the LLVM project.

  1. Go back to the terminal in your editor.

  2. Install it using:

    • Windows:

      winget install martinstorsjo.llvm-mingw.ucrt
      

      This command will install the compiler binaries under C:\Users\user\AppData\Local\Microsoft\WinGet\Packages\MartinStorsjo...\llvm-mingw-20...\bin and will put this folder in your path.

    • macOS:

      brew install llvm
      
  3. Go back to your editor’s terminal.

  4. Check whether clang is installed and available in our environment by entering the following command in the terminal of the editor:

    clang
    

    You may see a message similar as follows should show up, especially if you are on Windows and macOS:

    clang: error: no input files
    

    If it does not and clang cannot be found, try the following in order:

    1. Probably your package manager modified your environment variable path, but the editor is not aware of this. Restart your editor.

    2. Maybe your package manager did not bother modifying your environment variable path. Refer to section Editing the environment variable path

  5. Now compile main.c using the following command:

    clang main.c
    

    You should get no output, which means your source code is compiled to machine code binary a.exe on Windows and a.out in Linux. You should see it in the EXPLORER column.

  6. Now run your program:

    ./a.exe
    

    We need to prefix our program with ./, because your current directory (.) is not part of your path by design.

    You should see no output. The returned number 42 can be seen in the return code:

    • Windows:

      $LASTEXITCODE
      
    • macOS, Linux:

      echo $?
      

    You should see as output:

    42
    

Creating a task for compiling our code#

Typing each time commands to the terminal to compile and run our program is not necessary. The editor features tasks, which can be configured to compile our code – or build in general – within the editor.

  1. Try to build your project using CtrlShiftb. You should see No build task ro run found. Configure Build Task....

  2. Click on the last message. You should see Create tasks.json file from template and other menu items related to settings prefixed with a gear icon βš™οΈ.

  3. Select Create tasks.json.... You should see different tasks templates including Others | Example to run an arbitrary external command

  4. Click on Others .... .vscode/tasks.json will be created and opened in a new tab. The template defines a task called echo.

  5. Let us try to run the created template. The task echo is not a build task right now, so it cannot be run using the build task.

    We will use not the menu but the command palette, which makes it possible to search for a menu item.

    Press CtrlShiftp. The command palette window should pop up.

  6. Type run task and then select Tasks: Run Task. The window will show many tasks including echo.

  7. Select echo. A new window will show up with Select for which kind of errors ... to scan the task output.

    Scanning the output is helpful, e.g. for:

    1. directly jumping to the error in our source code.

    2. to have an overview of issues in our code on the PROBLEMS tab (left to the TERMINAL tab).

    We are not going to use this feature, as we will directly get feedback about our program syntax mistakes on our editor window through the language server clangd that we will install later.

  8. Click on Continue without scanning the task output. A new terminal window prefixed with πŸ› οΈ echo should be opened and it will output Hello.

    Hello comes from the shell command echo Hello.

    So the template works.

Exercise 1

Convert the template to a task that

  1. compiles our code and then runs it. Use the two commands by chaining them using ;. This means cmd1; cmd2.

  2. is called build & run.

  3. Then run the task.

You should get an output similar to:

 *  Executing task: clang main.c; ./a.exe 


 *  The terminal process "... -Command clang main.c; ./a.exe" terminated with exit code: 1.

Selecting the default build task#

Now we will configure our task as the default build task.

  1. Press CtrlShiftb. You should see No build task to run found. ...

  2. Click on the only item. build & run task should show up.

  3. Select build & run. task.json task will be opened and you will see that tasks.json is augmented with the following lines:

             "problemMatcher": [],
             "group": {
                 "kind": "build",
                 "isDefault": true
             }
    

    These lines:

    1. Deactivate scanning of tasks output (problemMatcher)

    2. Select our task as the default

  4. Now CtrlShiftb again. It should compile and run your program without any prompts.

Tip

The build task automatically saves your project files before running the task. Don’t lose time with saving before executing the task.

Configuring code assistance using clangd#

Now replace your code with the following code. Use the existing project.

int main(){return n}

You should see some errors in your terminal. Do not fix them.

Wouldn’t it be much more convenient to see errors as you type? Tools exist for this purpose. We will install clangd which can pinpoint errors already on the editor and other features we will discover.

  1. Switch to a normal terminal in the editor (e.g., powershell) by pressing any key on the πŸ› οΈ build & run terminal.

  2. Try to run:

    • Windows: clangd.exe

    • Linux/macOS: clangd

    The command should output something similar to: clangd is a language server that provides IDE-like features to editors....

    clangd is part of the LLVM package that we installed before, so it should work, if the compiler clang works.

  3. Exit clangd by using on the terminal

language server

a tool that provides language intelligence tools like code completion, syntax highlighting, marking of warnings and errors

We will install clangd extension for our editor to be able to leverage clangd:

  1. Click on Extension on the leftmost bar. Extensions bar should show up.

    Using extensions we can add extra functionality to our editor.

  2. Search for clangd. Click on clangd (not other forks like Kylin Clangd).

  3. Click on Install. A window will pop up asking whether you want to trust.

  4. Click on Trust Publisher & Install. After the installation, you will notice that main.c tab title became red and shows 2 which is the number of errors.

  5. Go back to main.c tab. You will notice the red wavy underline under n. This points to an error.

  6. Hover on n. A small window will pop up mentioning the two errors. One of the errors can be fixed automatically using Quick Fix Ctrl..

  7. Use quick fix using the shortcut. It will open up a Quick Fix window and will suggest insert ';'.

  8. Select the suggestion. You will have one error left.

  9. Fix the last error by replacing n with 0.

  10. Build your project again. You should see no errors.

Saving our code on a repository#

Now we will learn how to store our code on a repository primarily for keeping a diary about our work and sharing it. We will use GitHub.

repository

(in context of version control systems) a data structure that stores metadata for a set of files or directory structure. The main purpose of a repository is to store a set of files, as well as the history of changes made to those files.

version control

the software engineering practice of controlling, organizing, and tracking different versions in history of computer files; primarily source code text files, but generally any type of file.

Keeping a history of changes is helpful if we or someone else who also work in the project would like to understand changes in the project which is useful for collaboration. Keeping a history helps also to roll changes back if something does not work as intended.

Keeping projects in a repository is also helpful to collaborate and share code. You will use it later to share or submit your projects. You probably already downloaded something from the code forges GitHub or GitLab, on which most of the open source in the world is organized.

code forge

a web interface to a version control system

We will setup Git in VS Code now.

  1. On the activity bar, click on Source Control.

  2. Install Git using the package manager: winget install git.git

    Alternatively
    1. Click on Download Git for Windows. A confirmation window will pop up.

    2. Click on Open. A web browser window will pop up.

    3. Download & install Git

  3. On the editor Source Control window click on reload. The editor’s window will refresh and you will see other button on the Source Control window.

  4. Click on Initialize Repository. Changes window will show up, which should show you the three files:

    1. main.c

    2. a.exe

    3. tasks.json

    _images/git-untracked-added.png

    Fig. 1 Two added files (A) and one Untracked (U) file on the Changes window. The mouse pointer hovers on a.exe, but the pointer cannot be seen.#

    You will see U beside these files. U stands for untracked, which means these files are not tracked by the repository. Typically only source files are tracked in a repository, so we will only track main.c and tasks.json.

  5. To track these two files, hover on the filenames and click on the symbol on each. You will an A on the right of the files, which stands for added.

  6. Click on the Message prompt to write a commit message. When we use repositories we make our changes in commits.

    Ideally each commit should be a set of changes that adds one or many describable feature like improved user name handling or added robot program. The advantage is that the programmer can roll back changes if these features led to problems later. Sometimes people don’t want to put so much structuring work and use a repository as a diary and commit code at the end of the day, which is not a good practice in a professional environment.

    This is our first commit, so use the message initial.

  7. Click on Commit. You will see your first commit on the Graph window below.

changeset

list of differences between two successive versions in a repository

commit

the operation of committing such a changeset to the repository

Pushing code to a code forge#

The repository we used is until now local to our computer. To share our work, we must push our changes for a code forge like GitHub.

  1. On the Graph window, click on Publish Branch. A confirmation window will pop up to sign in using GitHub.

  2. Allow. A new window will pop up with authentication code.

  3. Copy & Continue to GitHub. A new confirmation window will pop up.

  4. Open. A browser window will pop up.

    Create (if you don’t have an account) and login to GitHub. You will be forwarded to the Device Activation page on GitHub.

  5. Paste your code. Authorize Visual Studio Code should come up.

    If the code is not available anymore, go back to the editor and start from step 1.

  6. Click on Authorize Visual-Studio-Code. You should see Congratulations …

  7. You can close the browser.

  8. A window will pop up with two options β€” whether you want to publish privately or publicly. You will use this repository to submit your work, so: select Publish to GitHub public repository ...

  9. You will get the notification Successfully published ....

    If you missed the notification, click on the (bell) icon in the below right corner of the editor.

  10. On the notification, click on Open on GitHub. A confirmation window will pop up.

  11. Open. Your browser will pop up and show you your repository on the GitHub.

    Use this address to share or submit your work.

  12. When we share work, we should also write some information about what the code is about in the README file. Click on Add a README.

  13. You can write something along the lines of:

    # Hello
    
    An example C program for my C programming course.
    

    Click on Preview to see how this text will be rendered.

  14. Commit changes.... Commit changes window will pop up.

  15. You can leave the automatic commit message. Commit changes. You will be forwarded to your main repository page.

  16. We made changes on GitHub, which are not visible on the repository on our computer. Remember that repositories are also used for collaboration.

  17. You can close the browser.

  18. On the editor, you should have a notification about: Would you like ... to periodically run "git fetch"?. Click Yes.

  19. On the Graph window you should see the commit that you have done on GitHub.

Creating a new project#

TODO

Autocompletion#

The language server clangd also assists us by suggesting code and completing partially written code. Let us experience this. Write the first characters of the following code – #inc and see the suggestions, then select #include <header>.

You can copy paste the rest of the code.

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main() {
int total=1000000,inside=0;
srand(time(0));
for(int i=0;i<total;i++) {
double x=(double)rand()/RAND_MAX;
double y=(double)rand()/RAND_MAX;
if (x*x+y*y<=1) inside++;}
double pi=4.0*inside/total;
printf("Estimated pi: %f\n",pi);}

Now build & run the program. It will print an estimation of the number pi.

Formatting#

Try to recognize different sections of the code. Is the code easy to follow and read? Think a while before you continue to read.

In my opinion, the code is hard to read. It is for example hard to see which curly braces ({ and }) belong together so that we can recognize components and subcomponents of the code – in other words hierarchies.

The programmers usually pay attention where they begin a new line or put the braces and this aids readability. Compare the following code pieces.

You don’t have to replace the code for pi estimation, we will use it later.

#include <stdio.h>
int main() {
for(int i=0;i<4;i++){printf("%d ", i*i);}}
#include <stdio.h>
int main() {
  for (int i = 0; i < 4; i++) {
    printf("%d ", i * i);
  }
}

Pay attention to:

  • alignment of { and } that belong together

  • spacing after ;

  • beginning a new line for a new statement like for and printf.

Do you agree that formatted code looks better?

Luckily the editor can format our code automatically using the language server clangd:

  1. Click on your code.

  2. Right click -> Format Document. Your code should now be formatted.

Formatting usually makes our code more readable, so let us automatize formatting. The editor can format whenever we save our code:

  1. File -> Preferences -> Settings. Settings will show up in a tab.

  2. Click on Search settings.

  3. Search for format

  4. Activate:

    • Editor: Format On Save

    • Editor: Format On Paste

    • Editor: Format On Type

Renaming symbols#

Another useful feature of clangd is renaming of symbols without renaming other unrelated strings. Let us try it together:

  1. Open the code above that calculates pi.

  2. Click near i as follows:

    _images/language-server-renaming-example.png
  3. Click f2 or right-click -> Rename Symbol. A small prompt will come up prefilled with symbol’s name i.

  4. Rename it to j. You will see that all i are renamed, but not i in the symbol inside below.

Renaming will be especially useful when we work on our code for a longer time where our code grows gradually. Then some tidying up and renaming of variable names may be needed for improving readability.

LLM code assistance#

We will setup LLM code assistance in our editor so that the LLM can interact with our code directly. Doing so saves you copy & paste time.

For using LLMs directly in our editor, we have two options:

  1. Running a local LLM on our computer

  2. Using cloud services like Mistral, OpenAI, Anthropic, etc.

Without a powerful graphics card or neural-network accelerator, the first option will probably be very slow. On the other hand most cloud services are not free to use including OpenAI. Even ChatGPT is free to use, using it as a remote cloud application, i.e., using their API (application programming interface), is not free.

As of the writing of this, Groq has a free tier, which allows about thousand requests per day for the model meta-llama/llama-4-scout-17b-16e-instruct, which should be sufficient for an educational setting. If you run out of credits, you can always use a free to use model through their web interface, e.g., Mistral, ChatGPT, etc.

Let us first get an API key from Groq and then use it in the Code LLM extension Continue.

Creating a Groq API key#

  1. Go to https://console.groq.com.

  2. Create an account. You will be logged in to the dashboard after creating an account.

  3. Click on Create API key. You will immediately be shown an API key.

  4. Copy the API key.

Installation of Continue#

  1. In Code, install the extension Continue - open-source AI code assistant. It may take about 1 minute.

    After the installation, you will see a settings icon right to the Auto Update on the tab of the extension and also on to the Continue app in the extension listing.

    You will also notice the new Continue icon on the activity bar.

  2. Click on one of the s. A menu will pop up.

  3. Click on Settings. Settings tab will open up and filter for the settings of Continue.

  4. (optional) Go to Telemetry Enabled and opt out telemetry if you desire.

  5. Close Settings.

  6. Move the Continue icon from the first step to the secondary sidebar on the right as shown here.

  7. Click on Or, configure your own models. A configuration window will open up.

  8. Right below the Connect button, click on Click here to view more providers. Add Chat Model window will pop up.

  9. Select the provider Groq.

  10. Select in the model drop-down menu Autodetect.

  11. Copy the API key that you have here to the corresponding field.

  12. Click Connect. The file continue_tutorial.py will open up in a new tab. Additionally the Continue tool will show you a window where you can configure Models for different purposes, e.g., Chat, Autocomplete, etc.

  13. For Chat, Edit, and Apply, choose the model that contains llama-4-scout in its name.

    We are not going to setup Autocomplete and Rerank.

  14. Click on the on the left side of Models to collapse the toolbar.

Using the LLM for explaining and formatting#

  1. Close continue_tutorial.py tab, we are going to try the agent on the pi-estimator code.

  2. On the Continue tab, if the a subwindow called Create Your Own Assistant is open, you can close it.

  3. Click on the tab with the pi-estimator code.

  4. Write on the prompt explain me the code line by line and press AltEnter. Without Alt, Continue does not send your code to the agent.

    You should see an explanation.

  5. Now write format code. LLM should reply with formatted code. I got the following:

    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    
    int main() {
        int total = 1000000;
        int inside = 0;
    
        srand(time(0));
    
        for (int i = 0; i < total; i++) {
            double x = (double)rand() / RAND_MAX;
            double y = (double)rand() / RAND_MAX;
    
            if (x * x + y * y <= 1)
                inside++;
        }
    
        double pi = 4.0 * inside / total;
        printf("Estimated pi: %f\n", pi);
    
        return 0;
    }
    

    Even I prompted format code, the model added also return 0; line, which is not required, but can be part of an explicit code style. So pay attention that you review the changes block by block.

    You notice that formatting looks different than the language server we used. LLM is able to recognize blocks that logically belong together and insert newlines accordingly, which can be a superpower compared to the clangd formatter we used.

  6. To apply the changes: On the right top corner of the code reply, click on Apply. Accept | Reject blocks will appear in your code.

    As recommended before, accept or reject block by block.

Tip

One of the learning goals of this course is to identify and explain core programming concepts without an LLM to be able to criticize the output of a LLM. I recommend you to write the programs yourself and ask the LLM as a second step only for getting feedback, improvements or explanations.

Summary#

πŸŽ‰ Congratulations, now you are ready to learn C coding.

Overview of the shortcuts we have used#

CtrlShiftb

build project

CtrlShiftp

command palette

Ctrl.

quick fix