C Language – An Integrated Example (The Five Grammatical Elements of a Programming Language)
1. Integrated Example
The following example is a comprehensive example that uses all five grammar elements of the C programming language (variables, operators, statements, control, and functions) and includes all 32 reserved keywords and 12 preprocessor directives under the C90 standard in a single compilable source file.
exam.c
/*
* exam.c - Comprehensive C grammar example
*
*/
// #include - include C headers
#include <stdio.h>
#include <stdlib.h>
// #define - define macro
#define MAX_COUNT 5
#define BUF_SIZE 64
#define DEBUG_LEVEL 0
// #undef - undefine macro
#undef DEBUG_LEVEL
#define DEBUG_LEVEL 1
// #ifndef / #endif - compile only if macro is not defined
#ifndef RELEASE
#define RELEASE
#endif
// #if / #elif / #else / #endif - conditional compilation
#if DEBUG_LEVEL == 0
#define BUILD_TYPE "Release"
#elif DEBUG_LEVEL == 1
#define BUILD_TYPE "Debug"
#else
#define BUILD_TYPE "Unknown"
#endif
// #ifdef / #error / #endif - trigger a compile error when a specific macro is defined
#ifdef DEBUG_MODE
#error "DEBUG_MODE must not be defined in production builds"
#endif
// #line - reset compiler line number to 100
#line 100
// #pragma - compiler directive
// The following handles warnings to ignore intentionally unused variables
#pragma GCC diagnostic ignored "-Wunused-variable"
/* ------------------------------------------------------------------ */
/* Type definitions (typedef struct enum union) */
/* ------------------------------------------------------------------ */
// typedef + struct
typedef struct {
int x;
int y;
} Point;
// typedef + union
typedef union {
int i;
float f;
} Number;
// typedef + enum
typedef enum {
STATUS_IDLE = 0,
STATUS_RUNNING = 1,
STATUS_DONE = 2
} Status;
/* ------------------------------------------------------------------ */
/* File-scope storage class keywords */
/* ------------------------------------------------------------------ */
// extern - indicates that a function in another .c file is used here
extern void external_log(const char *msg);
// static - internal linkage; value persists across calls
static int call_count = 0;
// volatile - value may change outside normal program flow
volatile int interrupt_flag = 0;
/* ------------------------------------------------------------------ */
/* Function prototypes */
/* ------------------------------------------------------------------ */
int increase(int value);
void print_info(const char *label, int value);
double compute_average(int *arr, unsigned int size);
void demonstrate_types(void);
/* main function */
int main(void)
{
// auto - automatic (local) storage duration
auto int count = 0;
// const - read-only variable
const int LIMIT = 3;
// register - hint to store in CPU register
register int i;
// basic type keywords
short s = 10;
long l = 100000L;
unsigned int u = 255u;
signed char sc = -1;
char grade = 'A';
float ratio = 0.75f;
double pi = 3.14159265358979;
// composite types
Point p = {10, 20};
Number num;
Status status = STATUS_IDLE;
int arr[MAX_COUNT];
// static local variable
static int run_count = 0;
// intentionally unused variable to demonstrate #pragma behavior
int unused_var;
// operations: arithmetic, comparison, logical
count = count + 1; // + (arithmetic)
count = count - 1; // - (arithmetic)
u = u / 5; // / (arithmetic)
s = (short)(s * 2); // * (arithmetic)
num.i = (int)pi % 3; // % (arithmetic)
run_count++;
call_count++;
// sizeof operator
printf("sizeof(int) = %u bytes\n", (unsigned)sizeof(int));
printf("sizeof(double) = %u bytes\n", (unsigned)sizeof(double));
printf("sizeof(Point) = %u bytes\n", (unsigned)sizeof(Point));
// control: while
while (count < MAX_COUNT) {
if (count == LIMIT) { // if
break; // break
} else { // else
count = increase(count);
}
}
// control: do-while + continue
do {
call_count++;
if (call_count % 2 == 0) {
continue; // continue
}
print_info("call_count", call_count);
} while (call_count < 4); // while
// control: for
for (i = 0; i < MAX_COUNT; i++) {
arr[i] = i + 1;
}
// control: switch / case / default
switch (status) {
case STATUS_IDLE:
status = STATUS_RUNNING;
break;
case STATUS_RUNNING:
status = STATUS_DONE;
break;
default:
break;
}
// control: goto
if (interrupt_flag != 0) {
/*
Since `goto` makes program flow harder to trace,
it should be avoided whenever possible except for exceptional
error-handling sections.
*/
goto error_exit;
}
// statements: function calls, input/output
demonstrate_types();
print_info("count", count);
print_info("LIMIT", LIMIT);
print_info("status", (int)status);
printf("build = %s\n", BUILD_TYPE);
printf("grade = %c\n", grade);
printf("ratio = %.2f\n", ratio);
printf("pi = %.5f\n", pi);
printf("short = %d\n", s);
printf("long = %ld\n", l);
printf("uint = %u\n", u);
printf("schar = %d\n", (int)sc);
printf("point = (%d, %d)\n", p.x, p.y);
printf("num.i = %d\n", num.i);
{
double avg = compute_average(arr, MAX_COUNT);
printf("avg = %.1f\n", avg);
}
return 0; /* return */
error_exit:
fprintf(stderr, "Error: interrupt detected.\n");
return 1;
}
/* increase - increment value by 1 and return */
int increase(int value)
{
return value + 1;
}
/* print_info - print string label and integer value */
void print_info(const char *label, int value)
{
printf("%-6.6s = %d\n", label, value);
}
/* compute_average - calculate arithmetic mean of int array */
double compute_average(int *arr, unsigned int size)
{
int sum = 0;
unsigned int j;
for (j = 0; j < size; j++) {
sum += arr[j];
}
return (double)sum / size;
}
/* demonstrate_types - example usage of C90 basic types */
void demonstrate_types(void)
{
signed int si = -10;
unsigned int ui = 10;
short int sh = 5;
long int li = 1000L;
char c = 'Z';
float f = 1.5f;
double d = 2.5;
printf("[types] si=%d ui=%u sh=%d li=%ld c=%c f=%.1f d=%.1f\n",
si, ui, sh, li, c, f, d);
}
exam_func.c
/*
* Implementation file for the function declared as extern in exam.c
*/
#include <stdio.h>
/* extern function example */
void external_log(const char *msg)
{
printf("[log] %s\n", msg);
}
- Coverage: variables, operations, statements, control statements, functions
- Components: C90 keywords, preprocessor directives, struct/union/enum, function call flow
1.1. Execution Result
$ gcc -Wall -std=c11 -o exam exam.c exam_func.c $ ./exam sizeof(int) = 4 bytes sizeof(double) = 8 bytes sizeof(Point) = 8 bytes call_c = 3 [types] si=-10 ui=10 sh=5 li=1000 c=Z f=1.5 d=2.5 count = 3 LIMIT = 3 status = 1 build = Debug grade = A ratio = 0.75 pi = 3.14159 short = 20 long = 100000 uint = 51 schar = -1 point = (10, 20) num.i = 0 avg = 3.0
1.2. Control Flow
main() starts
│
├─ while (count < MAX_COUNT)
│ ├─ if (count == LIMIT) → break ← exits loop when count becomes 3
│ └─ else → count = increase(count)
│
├─ do-while (call_count < 4)
│ ├─ if (call_count % 2 == 0) → continue ← skips output on even values
│ └─ print_info(...)
│
├─ for (i = 0; i < MAX_COUNT; i++)
│ └─ arr[i] = i + 1 ← initializes to {1, 2, 3, 4, 5}
│
├─ switch (status)
│ ├─ STATUS_IDLE → STATUS_RUNNING
│ ├─ STATUS_RUNNING → STATUS_DONE
│ └─ default → break
│
├─ if (interrupt_flag != 0) → goto error_exit
│
├─ output statements
│
└─ return 0
error_exit:
└─ fprintf(stderr, ...) → return 1