C Programming Building Blocks

These are simple C programs that provide an intuitive understanding of the entire language. These are building blocks of programs that can help you understand any complex program. This even this entire Learn To Solve It can be approached if the reader has the intuitive understanding of these building block C Programs.

Integer and float data types

#include <stdio.h>

int main(int argc, char *argv[]) {
    int int_variable;
    float float_variable;

    int_variable = 10;
    float_variable = 10.10;

    printf("The value of the integer variable is %d\n", int_variable);
    printf("The value of my float variable is %f\n", float_variable);
}

Character Datatype

#include <stdio.h>

int main(int argc, char *argv[]) {
    char char_value;
    char_value = 'c';
    printf("The value of my character datatype is %c\n", char_value);

    int i = 0;
    for (i = 0; i <128; i++) {
        char_value = (char) i;
        printf("The value of my character datatype is %c for the integer value %d \n", char_value, i);
    }
}

Character Array and String

#include<stdio.h>

int main(int argc, char *argv[]) {
    char s[]  = {'s', 't', 'r', 'i', 'n', 'g', '\0'};
    printf("%s\n", s);

    char s1[10];
    int i, j;
    for (i = 65, j = 0; i < 70; i++) {
        s1[j] = (char) i;
        j++;
    }
    s1[j] = '\0';

    printf("%s\n", s1);

    char s2[] = "string";

    printf("%s\n", s2);

}

Pointers

#include <stdio.h>

int main() {
    printf("size of a short is %d\\n", sizeof(short));
    printf("size of a int is %d\\n", sizeof(int));
    printf("size of a long is %d\\n", sizeof(long));
}
#include <stdio.h>

int main(void) {

    int j, k;
    int *ptr;
    j = 1;
    k = 2;
    ptr = &k;
    printf("\n");
    printf("j has the value %d and is stored at %p\n", j, (void *) &j);
    printf("k has the value %d and is stored at %p\n", k, (void *) &k);
    printf("ptr has the value %p and is stored at %p\n", ptr, (void *) &ptr);
    printf("The value of the integer pointed to by ptr is %d\n", *ptr);

    return 0;
}
#include <stdio.h>


int main(void) {

    int my_array[] = {1, 23, 17, 4, -5, 100};
    int *ptr;
    int i;
    ptr = &my_array[0];
    printf("\n\n");
    for (i = 0; i < 6; i++) {
        printf("my_array[%d] = %d   ", i, my_array[i]);
        printf("ptr + %d = %d\n", i, *(ptr + i));
    }
    return 0;
}
#include <stdio.h>

int main(void) {

    char strA[80] = "A string to be used for demonstration purposes";
    char strB[80];

    char *pA;     /* a pointer to type character */
    char *pB;     /* another pointer to type character */
    puts(strA);   /* show string A */
    pA = strA;    /* point pA at string A */
    puts(pA);     /* show what pA is pointing to */
    pB = strB;    /* point pB at string B */
    putchar('\n');       /* move down one line on the screen */
    while (*pA != '\0')   /* line A (see text) */
    {
        *pB++ = *pA++;   /* line B (see text) */
    }
    *pB = '\0';          /* line C (see text) */
    puts(strB);          /* show strB on screen */
    return 0;
}
#include <stdio.h>

#define ROWS 5
#define COLS 10

int multi[ROWS][COLS];

int main(void) {
    int row, col;
    for (row = 0; row < ROWS; row++) {
        for (col = 0; col < COLS; col++) {
            multi[row][col] = row * col;
        }
    }

    for (row = 0; row < ROWS; row++) {
        for (col = 0; col < COLS; col++) {
            printf("\n%d  ", multi[row][col]);
            printf("%d ", *(*(multi + row) + col));
        }
    }

    return 0;
}

Structures

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

int main(int argc, char *argv[]) {
    struct tag {
        char lname[20];
        char fname[20];
        int age;
        float rate;
    };

    struct tag my_struct;

    strcpy(my_struct.lname, "Kumaran");
    strcpy(my_struct.fname, "Senthil");

    printf("\n%s ", my_struct.fname);
    printf("%s\n", my_struct.lname);

    return 0;
}

Pointer to Structures

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

struct tag {                     /* the structure type */
    char lname[20];             /* last name */
    char fname[20];             /* first name */
    int age;                    /* age */
    float rate;                 /* e.g. 12.75 per hour */
};

struct tag my_struct;           /* define the structure */
void show_name(struct tag *p);  /* function prototype */

int main(void) {
    struct tag *st_ptr;         /* a pointer to a structure */
    st_ptr = &my_struct;        /* point the pointer to my_struct */
    strcpy(my_struct.lname, "Jensen");
    strcpy(my_struct.fname, "Ted");
    printf("\n%s ", my_struct.fname);
    printf("%s\n", my_struct.lname);
    my_struct.age = 63;
    show_name(st_ptr);          /* pass the pointer */
    return 0;
}

void show_name(struct tag *p) {
    printf("\n%s ", p->fname);  /* p points to a structure */
    printf("%s ", p->lname);
    printf("%d\n", p->age);
}

TypeDefs

#include <stdio.h>

#define ROWS 5
#define COLS 10

int main(int argc, char *argv[]) {
    int multi[ROWS][COLS];

    int row, col;

    for (row = 0; row < ROWS; row++) {
        for (col = 0; col < COLS; col++) {
            multi[row][col] = row * col;
        }
    }

    for (row = 0; row < ROWS; row++) {
        for (col = 0; col < COLS; col++) {
            printf("\n%d ", multi[row][col]);
            printf("%d ", *(*(multi + row) + col));
        }
    }
}

DEFS and IFDEFS Macros

#ifndef MY_PROGRAM_HEADER
#define MY_PROGRAM_HEADER

#define SQUARE(x) ((x) * (x))
#define WINDOWS 1
#define LINUX 2
#define PLATFORM LINUX

#include <stdio.h>

int main(int argc, char *argv[]) {
    int num = 20;
    printf("Square of the number is %d\n", SQUARE(num));

    // Conditinal Compilation

#ifdef PLATFORM
#if PLATFORM == WINDOWS
    printf("Compiling for Windows\n");
#define PATH_SEPARATOR "\\"
#elif PLATFORM == LINUX
    printf("Compiling for Linux\n");
#endif
#define PATH_SEPARATOR "/"
#else
#error Platform not defined!
#endif

}

#endif // MY_PROGRAM_HEADER

Union and Pointer to Unions

#include <stdio.h>

union Data {
    int i;
    float f;
    char str[20];
};

int main(int argc, char *argv[]) {
    union Data data;
    union Data *ptr;

    ptr = &data;

    data.i  = 42;
    printf("Integer value: %d \n", data.i);

    ptr->f = 3.14;
    printf("Float value: %f\n", data.f);

    printf("Integer value again: %d \n", data.i);
    printf("Since Union share memory, the integer value is lost.");
}

Bitwise manipulation

#include <stdio.h>
#include <limits.h>

/**
 * %b specifier is available since C23
 * https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2630.pdf
 * if %b is not available for your compiler
 * we can use print_bin to see the binary
 **/

void print_bin(unsigned char byte)
{
    int i = CHAR_BIT; /* however many bits are in a byte on your platform */
    while(i--) {
        putchar('0' + ((byte >> i) & 1)); /* loop through and print the bits */
    }
}

int main(int argc, char *argv[]) {
    unsigned char a = 12 ; // Binary 00001100
    unsigned char b = 10;  // Binary 00001010

    printf("Original Values: \n");
    printf("a = %d (Binary: %08b)\n", a, a);
    printf("b = %d (Binary: %08b)\n", b, b);

    printf("Decimal %d in Binary is", a);
    print_bin(a);

    printf("\n");

    printf("Decimal %d in Binary is", b);
    print_bin(b);

    // Bitwise AND (&)
    printf("\n Bitwise AND (&): \n");
    printf("%d & %d = %d (binary: %08b)\n", a, b, a & b, a & b);


    // Bitwise OR (|)
    printf("\n Bitwise OR (|): \n");
    printf("%d | %d = %d (binary: %08b)\n", a, b, a | b, a | b);

    // Bitwise XOR (^)
    printf("\n Bitwise XOR (^): \n");
    printf("%d ^ %d = %d (binary: %08b)\n", a, b, a ^b, a ^b);

    // Left shift <<
    printf("\n Left Shift (<<): \n");
    printf("%d << 1 = %d (binary: %08b)\n", a, a << 1, a << 1);

    // Right shift >>
    printf("\n Right Shift (>>): \n");
    printf("%d >> 1 = %d (binary: %08b)\n", a, a >> 1, a >> 1);

    // Bitwise NOT (~)
    printf("\n Bitwise NOT (~) \n");
    printf("~%d = %d (binary: %08b)\n", a, (unsigned char) ~a, (unsigned char)~a);
}

Using extern

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

// Declare the external variable
extern int shared_value;        // This tells compiler variable is defined elsewhere
extern void modify_value(void); // Declare external function

int main(int argc, char *argv[]) {
    printf("Initial shared value: %d\n", shared_value);


    // Modify the value in main
    shared_value = 20;
    printf("After modifying the value in main: %d\n", shared_value);


    modify_value();
    printf("After calling modify_value: %d\n", shared_value);

    return 0;
}
#ifndef LEARNTOSOLVEIT_OTHER_H
#define LEARNTOSOLVEIT_OTHER_H

#include <stdio.h>
int shared_value = 10;

void modify_value(void) {
    shared_value *= 2;
    printf("Modified in other.h : %d\n", shared_value);
}

#endif //LEARNTOSOLVEIT_OTHER_H

A practical program demonstrating the use of externs

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

/**
 * $ gcc p18_extern_config.c config.c -o p18_extern_config
 * $ ./p18_extern_config
 * Max connections: 100
 **/

int main(int argc, char *argv[]) {
    init_config();
    printf("Max connections: %d\n", app_config.max_connections);
    return 0;
}
#ifndef LEARNTOSOLVEIT_CONFIG_H
#define LEARNTOSOLVEIT_CONFIG_H

extern struct Config {
    int max_connections;
    char *server_name;
    int port;
} app_config;

extern void init_config(void);
#endif //LEARNTOSOLVEIT_CONFIG_H
#include "config.h"

struct Config app_config = {
        .max_connections = 100,
        .server_name = "localhost",
        .port = 8080
};

void init_config(void) {
    // Initialize configuration
}

Using enums

#include <stdio.h>


enum DayOfWeek {
    SUNDAY = 1,
    MONDAY,
    TUESDAY,
    WEDNESDAY,
    THURSDAY,
    FRIDAY,
    SATURDAY
};

enum TaskStatus {
    PENDING, // Will start at 0
    IN_PROGRESS,
    COMPLETED,
    CANCELLED
};

int main(int argc, char *argv[]) {
    enum DayOfWeek today = WEDNESDAY;
    printf("Day number of the week %d\n", today);


    enum TaskStatus status = PENDING;
    printf("\nTask Status: \n");
    printf("Initial Status: %d\n", status);

    status = COMPLETED;
    printf("Updated status: %d\n", status);

    if (status == COMPLETED) {
        printf("Task is Complete!\n");
    }

    return 0;
}

malloc and calloc

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

#define COLS 5


int main(int argc, char *argv[]) {

    typedef int RowArray[COLS];
    RowArray *rptr;

    int nrows = 10;
    int row, col;

    rptr = malloc(nrows * COLS * sizeof(int));

    for (row = 0; row < nrows; row++) {
        for (col = 0; col < COLS; col++) {
            rptr[row][col] = row * col;
        }
    }

    free(rptr);
    return 0;
}