Skip to main content

c

Low-level programming language providing direct memory access and hardware control, serving as the foundation for operating systems and embedded systems.

Source facts

Repository
ffsshhttiikk/opencode-agents-skills
Last source activity
February 28, 2026 at 22:48
Detected SKILL.md language
English
Stars
3
Forks
2

Install options

The review-first prompt is selected by default. You can switch to a direct command or download a local copy.

Review the source files

Read SKILL.md and any companion files shown by SkillsMP before deciding whether to install.

Showing SKILL.md

SKILL.md
Source instructions · Read-only preview
name
C
description
Low-level programming language providing direct memory access and hardware control, serving as the foundation for operating systems and embedded systems.
license
BSD License (reference implementation)
compatibility
C11/C17 standard
audience
Systems programmers, embedded developers, OS developers
category
Programming Languages
# C ## What I do I am a low-level, imperative programming language developed by Dennis Ritchie at Bell Labs in 1972. I provide direct access to memory through pointers, close-to-hardware operations, and minimal runtime overhead. I am the foundation for Unix-like operating systems, embedded systems, device drivers, and high-performance applications. I compile directly to machine code, offering unmatched control over system resources and performance. My influence extends to C++, Java, Python, and many other languages that adopted my syntax and paradigms. ## When to use me Use C when building operating systems and kernels, embedded systems with limited resources, device drivers and firmware, high-performance computing applications, compilers and interpreters, or when you need complete control over memory and hardware. ## Core Concepts - **Pointers and Memory Addresses**: Direct manipulation of memory addresses enabling efficient data structures and system-level programming. - **Manual Memory Management**: Explicit allocation (malloc) and deallocation (free) requiring careful memory lifecycle management. - **Preprocessor Directives**: Text substitution before compilation for macros, conditional compilation, and file inclusion. - **Static Typing with Weak Enforcement**: Types are checked but can be casted, requiring careful attention to type compatibility. - **Function and Control Flow**: Structured programming with if/else, switch, while, for, and do-while constructs. - **Structures and Unions**: Compound data types for grouping variables and memory-efficient variant types. - **Bit Manipulation**: Direct operations on individual bits using bitwise operators for flags, masks, and hardware registers. - **Header Files and Linking**: Separate declaration (header files) from definition (source files) with compilation and linking phases. - **Standard Library**: Rich standard library for I/O, string manipulation, memory allocation, and mathematical operations. - **Variable Scope and Lifetime**: Block scope, function scope, file scope, and dynamic storage duration. ## Code Examples **Pointers and Memory Management:** ```c #include <stdio.h> #include <stdlib.h> #include <string.h> typedef struct { char name[50]; int age; float score; } Student; Student* create_student(const char* name, int age, float score) { Student* s = (Student*)malloc(sizeof(Student)); if (s == NULL) { fprintf(stderr, "Memory allocation failed\n"); return NULL; } strncpy(s->name, name, sizeof(s->name) - 1); s->name[sizeof(s->name) - 1] = '\0'; s->age = age; s->score = score; return s; } void free_student(Student* s) { free(s); } int main() { Student* students[3]; const char* names[] = {"Alice", "Bob", "Charlie"}; int ages[] = {20, 21, 22}; float scores[] = {85.5, 90.0, 78.5}; for (int i = 0; i < 3; i++) { students[i] = create_student(names[i], ages[i], scores[i]); } for (int i = 0; i < 3; i++) { printf("Student %d: %s, Age: %d, Score: %.1f\n", i + 1, students[i]->name, students[i]->age, students[i]->score); } for (int i = 0; i < 3; i++) { free_student(students[i]); } return 0; } ``` **Pointers and Arrays:** ```c #include <stdio.h> void reverse_array(int* arr, size_t size) { int* start = arr; int* end = arr + size - 1; while (start < end) { int temp = *start; *start = *end; *end = temp; start++; end--; } } void print_array(const int* arr, size_t size) { for (size_t i = 0; i < size; i++) { printf("%d ", arr[i]); } printf("\n"); } int main() { int numbers[] = {1, 2, 3, 4, 5}; size_t size = sizeof(numbers) / sizeof(numbers[0]); printf("Original array: "); print_array(numbers, size); reverse_array(numbers, size); printf("Reversed array: "); print_array(numbers, size); return 0; } ``` **Function Pointers and Callbacks:** ```c #include <stdio.h> #include <stdlib.h> typedef int (*compare_fn)(const void*, const void*); int compare_ints(const void* a, const void* b) { int val_a = *(const int*)a; int val_b = *(const int*)b; return (val_a > val_b) - (val_a < val_b); } void bubble_sort(void* arr, size_t n, size_t size, compare_fn cmp) { char* base = (char*)arr; for (size_t i = 0; i < n - 1; i++) { for (size_t j = 0; j < n - i - 1; j++) { char* a = base + j * size; char* b = base + (j + 1) * size; if (cmp(a, b) > 0) { char temp[64]; memcpy(temp, a, size); memcpy(a, b, size); memcpy(b, temp, size); } } } } int main() { int arr[] = {64, 34, 25, 12, 22, 11, 90}; size_t n = sizeof(arr) / sizeof(arr[0]); qsort(arr, n, sizeof(int), compare_ints); printf("Sorted array: "); for (size_t i = 0; i < n; i++) { printf("%d ", arr[i]); } printf("\n"); return 0; } ``` ## Best Practices 1. **Always Initialize Variables**: Uninitialized variables contain garbage values; always initialize pointers and variables before use. 2. **Check malloc Return Values**: Always check if malloc/calloc/realloc returned NULL before using the allocated memory. 3. **Match malloc and free**: Every allocation must have exactly one corresponding free to prevent memory leaks. 4. **Use sizeof for Portability**: Use sizeof(type) or sizeof(variable) instead of hardcoded sizes. 5. **Prefer size_t for Sizes**: Use size_t for sizes, counts, and indices to avoid signed/unsigned comparison warnings. 6. **Use const Correctness**: Mark function parameters as const when they shouldn't be modified. 7. **Beware of Integer Overflow**: Check for overflow in calculations, especially with user-controlled input. 8. **Use Restrict Keyword**: Use restrict pointers to tell compiler objects don't overlap, enabling optimizations. 9. **Write Portable Code**: Avoid compiler-specific extensions and platform-dependent assumptions. 10. **Use Static Analysis Tools**: Run valgrind, AddressSanitizer, and static analyzers to catch memory errors and undefined behavior.
View on GitHub