# 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: 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:

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

The question should be specific, self-contained, and written in natural language.
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.
