Slices in C

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// Function to print an array of strings
void printStringArray(char **arr, int size) {
    printf("[");
    for (int i = 0; i < size; i++) {
        printf("%s", arr[i]);
        if (i < size - 1) printf(" ");
    }
    printf("]");
}

int main() {
    // In C, we use arrays instead of slices. 
    // We'll use pointers to char (char*) to represent strings.
    
    // An uninitialized array of pointers to char
    char **s = NULL;
    int s_size = 0;
    printf("uninit: ");
    printStringArray(s, s_size);
    printf(" %s %d\n", s == NULL ? "true" : "false", s_size == 0);

    // To create an empty array with non-zero length, we use malloc
    s_size = 3;
    s = (char**)malloc(s_size * sizeof(char*));
    for (int i = 0; i < s_size; i++) {
        s[i] = (char*)malloc(1); // Empty string
        s[i][0] = '\0';
    }
    printf("emp: ");
    printStringArray(s, s_size);
    printf(" len: %d\n", s_size);

    // We can set and get just like with arrays
    free(s[0]); s[0] = strdup("a");
    free(s[1]); s[1] = strdup("b");
    free(s[2]); s[2] = strdup("c");
    printf("set: ");
    printStringArray(s, s_size);
    printf("\n");
    printf("get: %s\n", s[2]);

    printf("len: %d\n", s_size);

    // To append elements, we need to reallocate memory
    s_size += 3;
    s = (char**)realloc(s, s_size * sizeof(char*));
    s[3] = strdup("d");
    s[4] = strdup("e");
    s[5] = strdup("f");
    printf("apd: ");
    printStringArray(s, s_size);
    printf("\n");

    // To copy an array, we allocate new memory and copy each string
    char **c = (char**)malloc(s_size * sizeof(char*));
    for (int i = 0; i < s_size; i++) {
        c[i] = strdup(s[i]);
    }
    printf("cpy: ");
    printStringArray(c, s_size);
    printf("\n");

    // Slicing in C requires manual index management
    printf("sl1: [%s %s %s]\n", s[2], s[3], s[4]);
    printf("sl2: ");
    printStringArray(s, 5);
    printf("\n");
    printf("sl3: ");
    printStringArray(s + 2, 4);
    printf("\n");

    // We can declare and initialize an array of strings in a single line
    char *t[] = {"g", "h", "i"};
    int t_size = sizeof(t) / sizeof(t[0]);
    printf("dcl: ");
    printStringArray(t, t_size);
    printf("\n");

    // C doesn't have built-in utility functions for arrays, so we'd need to implement them ourselves

    // Multi-dimensional arrays in C
    int rows = 3;
    int **twoD = (int**)malloc(rows * sizeof(int*));
    for (int i = 0; i < rows; i++) {
        int innerLen = i + 1;
        twoD[i] = (int*)malloc(innerLen * sizeof(int));
        for (int j = 0; j < innerLen; j++) {
            twoD[i][j] = i + j;
        }
    }
    printf("2d: [");
    for (int i = 0; i < rows; i++) {
        printf("[");
        for (int j = 0; j < i + 1; j++) {
            printf("%d", twoD[i][j]);
            if (j < i) printf(" ");
        }
        printf("]");
        if (i < rows - 1) printf(" ");
    }
    printf("]\n");

    // Free allocated memory
    for (int i = 0; i < s_size; i++) free(s[i]);
    free(s);
    for (int i = 0; i < s_size; i++) free(c[i]);
    free(c);
    for (int i = 0; i < rows; i++) free(twoD[i]);
    free(twoD);

    return 0;
}

This C code demonstrates concepts similar to Go’s slices, but using C’s array and pointer mechanisms. Here are some key points:

  1. In C, we use arrays and pointers instead of slices. Dynamic arrays are created using malloc and realloc.

  2. Strings in C are represented as character arrays (char*). We use functions like strdup to create copies of strings.

  3. Memory management is manual in C. We need to free any memory we malloc or realloc.

  4. C doesn’t have built-in utility functions for arrays like Go’s append or copy. We need to implement these operations manually.

  5. Slicing in C requires manual index management.

  6. Multi-dimensional arrays in C can be created using pointers to pointers.

  7. C doesn’t have a built-in way to compare arrays like Go’s slices.Equal. We would need to implement such functionality ourselves.

This code provides a basic illustration of how to work with dynamic arrays and strings in C, which is conceptually similar to working with slices in Go, but with more manual memory management.