> For the complete documentation index, see [llms.txt](https://wiki.nushackers.org/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://wiki.nushackers.org/hackerschool/introduction-to-zig/working-with-c.md).

# Working with C

One of the great features of Zig is that it is fully compatible with C. Let's return to the *Hello, world!* example, this time using C to print instead of Zig.

```zig
const c = @cImport({
    @cInclude("stdio.h");
});

pub fn main() !void {
    _ = c.printf("Hello, world!\n");
}
```

That's it! Using the `cImport` directive, we can directly use C code inside of Zig. Of course, please compile this to verify that it works as expected.

{% hint style="info" %}
For the rest of this page, we'll be working across multiple files. The filenames will be given in a comment that precedes the source code. Creating a new directory to store all these source files is encouraged, so that it doesn't get too messy.
{% endhint %}

## Custom C code

Let's write some of our own code instead of using the C standard library. Our custom C program will have just a single `greet` function, that says hello to the name passed as a parameter.&#x20;

```c
// In file /c-src/greeter.h

void greet(const char *name);

// In file /c-src/greeter.c

#include "greeter.h"
#include <stdio.h>

void greet(const char *name) {
  if (name == NULL) {
    printf("Hello, world!\n");
  } else {
    printf("Hello, %s!\n", name);
  }
}
```

Let's verify that this works as a C program first. We can create a temporary main file for the C program.

```c
// In file /c-src/main.c

#include "greeter.h"
#include <stdio.h>

int main() {
  greet("Alice");
  greet("Bob");
  greet(NULL);
  return 0;
}
```

And then compile it using `gcc` as with any other C program.

```bash
$ gcc -o greet c-src/greeter.c c-src/main.c  
$ ./greet
Hello, Alice!
Hello, Bob!
Hello, world!
```

It works! So how do we get `gcc` to work with Zig? Ah! We unveil the secret behind Zig's ability to handle C code so well. It *comes with a C compiler :O*

```bash
$ zig cc -o greet c-src/greeter.c c-src/main.c  
$ ./greet
Hello, Alice!
Hello, Bob!
Hello, world!
```

{% hint style="info" %}
Okay, if you're cheeky and try doing `zig cc --help`, you might discover that it's actually Clang (on a Macbook at least). But the creator of Zig actually [wrote about this](https://andrewkelley.me/post/zig-cc-powerful-drop-in-replacement-gcc-clang.html), and TL;DR it is Clang but smaller and does more out-of-the-box.
{% endhint %}

Insane! Let's continue by trying using this C code in Zig instead of just C. We can start by modifying our build file to look for `greeter.h` in the correct place.

```zig
// In file /build.zig

const std = @import("std");

pub fn build(b: *std.Build) void {
    const exe = b.addExecutable(.{
        .name = "greet",
        .root_source_file = b.path("src/main.zig"),
        .target = b.standardTargetOptions(.{}),
        .optimize = b.standardOptimizeOption(.{}),
    });
    exe.addIncludePath(b.path("c-src"));

    b.installArtifact(exe);

    const run_cmd = b.addRunArtifact(exe);
    run_cmd.step.dependOn(b.getInstallStep());

    const run_step = b.step("run", "Run the app");
    run_step.dependOn(&run_cmd.step);
}
```

Now, we can configure our `main.zig` file to import our custom `greeter.c`.

```zig
// In file /src/main.zig

const c = @cImport({
    @cInclude("greeter.c");
});

pub fn main() !void {
    c.greet("Alice");
    c.greet("Bob");
    c.greet(null);
}
```

We use the `zig build run` command instead of `zig run`, and we can see that everything works well!

```bash
$ zig build run
Hello, Alice!
Hello, Bob!
Hello, world!
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://wiki.nushackers.org/hackerschool/introduction-to-zig/working-with-c.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
