Inhaltsverzeichnis

improve

Viele Eigenschaften der Programmiersprache C basieren aufgrund der Nähe zu Assembly. Siehe auch C++/C#.

|Hwnd

Datentypen

Integer

// testValue
unsigned long long testValue     = 0xFFFFFFFFFFFFFFFF; // 18446744073709551615

// 1 byte -> [0-255] or [0x00-0xFF]
unsigned char    numberChar    = testValue; // 255

// 2 bytes -> [0-65535] or [0x0000-0xFFFF]
unsigned short    numberShort    = testValue; // 65535

// 4 bytes -> [0-4294967295] or [0x00000000-0xFFFFFFFF]
unsigned int     numberInt    = testValue; // 4294967295

// 4 bytes -> [0-4294967295] or [0x00000000-0xFFFFFFFF]
unsigned long    numberLong   = testvalue;

// 8 bytes -> [0-18446744073709551615] or [0x0000000000000000-0xFFFFFFFFFFFFFFFF]
unsigned long long     numberLongLong    = testValue; // 18446744073709551615

printf("%u %d %u %lu %llu", numberChar, numberShort, numberInt, numberLong, numberLongLong);

Float

Strtok

#include <string.h>

int main()
{
    
    char buf[] = "Hello world, how are you?";    
    char *token = strtok(buf, " ");            
    while(token != NULL) {
        printf("token: %s\n", token);
        token = strtok(NULL, " ");
    }

}

Nested strtok_r: https://stackoverflow.com/questions/4693884/nested-strtok-function-problem-in-c

Statische Variablen

// Eine statische Variable innerhalb einer Funktion behält ihren Wert auch zwischen mehreren Aufrufen.
void foo() {
    int a = 10;
    static int sa = 10;
    a += 5;
    sa += 5;
    printf("a = %d, sa = %d\n", a, sa);
}

int main() {
    int i;
    for (i = 0; i < 10; ++i) foo();
}

Pointer

Siehe Pointer in C.

int array[5];      // Declares 5 contiguous integers 
int *ptr = array;  // Arrays can be used as pointers 
ptr[0] = 1;        // Pointers can be indexed with array syntax 
*(array + 1) = 2;  // Arrays can be dereferenced with pointer syntax 
*(1 + array) = 3;  // Pointer addition is commutative 
2[array] = 4;      // Subscript operator is commutative
 
char a, b; // 2 chars = 2 bytes
char *zeiger; // einen (char) zeiger
 
zeiger = &a; // zeiger beinhaltet adresse von a
*zeiger = 'A'; // schreibe ein 'A' an die im Zeiger gespeicherte Adresse von a
printf("Kapitel %c\n", a);
 
zeiger = &b; // zeiger beinhaltet adresse von b
*zeiger = 'B'; // schreibe ein 'B' an die im Zeiger gespeicherte Adresse von b
printf("Kapitel %c\n", b);
 
// Pointer auf eine Funktion
void func(int *i) { 
    (*i)++; // *i++ geht nicht! Siehe Pointer Arithmetik 
}  
int main() {     
    void (*func_ptr)(int*) = &func;      
    int i = 0;    
    (*func_ptr)(&i);     
    printf("%d", i);
} 

Pass by reference

// pass a pointer
void modify(char *s){
    s[0] = 'g';
} 
 
int main(){
 
    char name[] = "New Holland";
    char *p_name = name;
    modify(p_name);
    printf("%s\n", name);
 
}
// pass the address of a pointer
void modify(char **s){
    char *new_name = "Old Holland";
    *s = new_name; 
} 
 
int main(){
 
    char name[] = "New Holland";
    char *p_name = name; 
    modify(&p_name);  
    printf("%s\n", name);
 
}

Constants

In compiled code there are several segments.

Every segment has a read only region where constants are stored. The compiler - and only the compiler - has to decide in which segment a variable get stored. And then, if the variable is a const it is stored in the r/o region of that specific segment.

#include <stdio.h>
 
int main() {
 
    const int a = 10;
    int b = 20;    
    const int *ptr = &a;
 
    printf("ptr: %d\n", *ptr);
 
    // error!!!
    *ptr = b;
 
    ptr = &b;
    printf("ptr: %d\n", *ptr);
 
}

See also constants in CPP

Binary Operations

void print(int n) {
    for (int i = 0; i < 8; i++) {
      printf("%d", !!((n << i) & 0x80));
    }
}
 
int main() {
 
   unsigned int a = 44;	/* 0010 1100 */ 
   unsigned int b = 13;	/* 0000 1101 */
 
   print(a);
   printf(" => a\n");
   print(b);
   printf(" => b\n--------\n");
 
   int c = 0;           
 
   c = a & b;      
   print(c); printf(" => a & b\n");
 
   c = a | b;      
   print(c); printf(" => a | b\n");
 
   c = a ^ b; 
   print(c); printf(" => a ^ b\n");
 
   c = ~a;      
   print(c); printf(" => ~a\n");
 
   c = a << 2;   
   print(c); printf(" => a << 2\n");
 
   c = a >> 2;    
   print(c); printf(" => a >> 2");
 
}
& (AND)
1   &   1   ==   1
1   &   0   ==   0
0   &   1   ==   0
0   &   0   ==   0

  00110010  - b
& 00010000  - & 0x10
----------
  00010000  - result

| (OR)
1   |   1   ==   1
1   |   0   ==   1
0   |   1   ==   1
0   |   0   ==   0

  00110010  - b
| 00000100  - | 0x04
----------
  00110110  - result

^ (XOR)
1   ^   1   ==   0
1   ^   0   ==   1
0   ^   1   ==   1
0   ^   0   ==   0

  00110010  - b
^ 00011000  - ^ 0x18
----------
  00101010  - result

  00101010  - b
^ 00011000  - ^ 0x18
----------
  00110010  - result
 
~ (Inversion, One complement)
 
00000011  - 0x03
11111100  - ~0x03  b

<< >> (Bit shifting)

00001100  - b
00110000  - b << 2
00000011  - b >> 2

Siehe Wahrheitstabelle. OneLoneCoder bitwise operations

Memory

Initialisieren

int main() {
    char str[20];
 
    // Setzen aller Elemente des Arrays auf 'A'
    memset(str, 'A', sizeof(str));
 
    printf("Initialized string: %s\n", str);
 
    return 0;
}

Kopieren

int main() {
    char source[] = "Hello, World!";
    char destination[20];
 
    // Kopieren des Inhalts von source nach destination
    memcpy(destination, source, sizeof(source));
 
    printf("Copied string: %s\n", destination);
 
    return 0;
}

Vergleichen

int main() {
    char str1[] = "abc";
    char str2[] = "abd";
 
    // Vergleichen der beiden Strings
    int result = memcmp(str1, str2, sizeof(str1));
 
    if (result == 0) {
        printf("Strings are equal.\n");
    } else if (result < 0) {
        printf("String 1 is less than String 2.\n");
    } else {
        printf("String 1 is greater than String 2.\n");
    }
 
    return 0;
}

Memory allocation

malloc and calloc are almost the same except calloc zerores out the block. malloc takes only the size as arg, calloc need size and type. realloc is king.

int main() {
 
    char *ptr = (char *)malloc(1024 * sizeof(char));
 
    char buf1[1024] = {'a'};
 
    strcat(ptr, buf1);
 
    ptr = realloc(ptr, 1024 * sizeof(char));
 
    char buf2[1024] = {'B'};
 
    strcat(ptr, buf2);
 
    printf("%s", ptr);
 
    free(ptr);
 
}

Buffer

#include <stdio.h>
#include <string.h>
 
#define SIZE 64
 
unsigned char memory[SIZE];
 
void print_memory() {
 
    printf("\n\t00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15");
 
    for(int i = 0; i < SIZE; i++) {
 
        if(i % 16 == 0)
            printf("\n%04d:\t", i);    
 
        printf("%02x ", memory[i]);     
 
    }   
 
    printf("\n");
}
 
int main() {
 
    int offset = 0;
 
    memset(memory, SIZE, 0);
 
    char str[] = "Hello world";
 
    memcpy(memory + offset, &str, strlen(str));
 
    offset += strlen(str);
 
    print_memory();
 
    float f = 3.14159f;
 
    memcpy(memory + offset, &f, sizeof(float));
 
    //offset += sizeof(float);
 
    print_memory();
 
    float tmp;
 
    memcpy(&tmp, &memory[offset], sizeof(float));
 
    printf("%f", tmp);
 
    return 1;
 
}

Files

FILE *f;
 
f = fopen("test.txt", "w");
char msg[] = "Hello world";
fwrite(msg, sizeof(msg), 1, f);
fclose(f);
 
f = fopen("test.txt", "r");
fseek(f, 0L, SEEK_END); 
int len = ftell(f); 
rewind(f);
char c, buffer[len];    
int i = 0;
while( fread(&c, sizeof(char), 1, f) > 0 ) buffer[i++] = c;
fclose(f);
buffer[i] = '\0';
printf("%s", buffer);
 
f = fopen("test.txt", "r");
char ch;      
while((ch = fgetc(f)) != EOF) printf("%c", ch);
fclose(f);
 
f = fopen("test.txt", "r");
char *line = NULL, read;
size_t len = 0;
while((read = getline(&line, &len, f)) > -1) printf("(%d) %s", read, line);
 
std::ifstream f("test.txt");
std::string data, line;
while(std::getline(f, line))
    data += line;   
std::cout << data;

Read 4 chars as a single int

FILE *f = fopen("test.txt", "rw");
char msg[] = {0x41,0x42,0x43,0x44};
fwrite(&msg, 1, sizeof(char), f);        
int *buffer;    
fread(&buffer, sizeof(int), 1, f);
fclose(f);    
printf("%d", buffer); // 0x41424344 = 1145258561

Piping in windows

#include <stdio.h>
#include <stdlib.h>
 
int main(void){
   char   psBuffer[128];
   FILE   *pPipe;
   if((pPipe = _popen("curl https://orf1.mdn.ors.at/out/u/orf1/q4a/manifest.m3u8", "rt")) == NULL ) exit(1);
   while(fgets(psBuffer, 128, pPipe)) {
      printf(psBuffer);
   }
   if (feof( pPipe)) printf("\nreturn %d\n", _pclose(pPipe));
   else printf( "Failed\n");
}

Data Structures

Arrays

#include <stdio.h>
 
int main() {
    // Erstellen eines Arrays mit 5 Elementen vom Typ int
    int array[5] = {1, 2, 3, 4, 5};
 
    // Zugriff auf Elemente des Arrays
    printf("Element 0: %d\n", array[0]);
    printf("Element 3: %d\n", array[3]);
 
    return 0;
}

Struct

struct Data {
   int i;
   float f;
   char *str;
};
 
int main( ) {
 
   // like this
   struct Data data = {10, 2.5};
 
   // or like this
   struct Data data;        
   data.i = 10;
   data.f = 2.5;
   data.str = "Hello world";
   printf( "data.i : %d\n", data.i);
   printf( "data.f : %f\n", data.f);
   printf( "data.str : %s\n", data.str);
}

Recursive Structure

typedef struct Node {
  char *value;
  struct Node* left;
  struct Node* right;
} Node;

Structure in anderer Structure

struct Details {
    char *name;
};
 
struct Entry {
    int id;
    struct Details details;
};
 
int main() {
    struct Entry entry = {1, "Manuel"};
    printf("id: %d\n", entry.id);
    printf("name: %s\n", entry.details.name);
}

Structures mit void* Pointern

typedef void (*Callback)();
 
struct Table {
    int id;
    char *type;
    void *val;
    Callback callback;
}; 
 
void myFunction(const char *s) {
    printf("%s", s);
} 
 
int main() {
    struct Table *t = malloc(sizeof(struct Table));                
    t->id = 1;
    t->type = "string"; 
    char s[] = "Hello world, heheh";
    t->val = &s;
    t->callback = myFunction;                
    t->callback(t->val);
}

Linked List

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>
 
struct node {
   int data;
   int key;
   char *c;
   struct node *next;
};
 
struct node *head = NULL;
struct node *current = NULL;
 
//display the list
void printList() {
   struct node *ptr = head;
   printf("\n[ ");
 
   //start from the beginning
   while(ptr != NULL) {
      printf("(%d,%d) ",ptr->key,ptr->data);
      ptr = ptr->next;
   }
 
   printf(" ]");
}
 
//insert link at the first location
void insertFirst(int key, int data) {
   //create a link
   struct node *link = (struct node*) malloc(sizeof(struct node));
 
   link->key = key;
   link->data = data;
 
   //point it to old first node
   link->next = head;
 
   //point first to new first node
   head = link;
}
 
//delete first item
struct node* deleteFirst() {
 
   //save reference to first link
   struct node *tempLink = head;
 
   //mark next to first link as first 
   head = head->next;
 
   //return the deleted link
   return tempLink;
}
 
//is list empty
bool isEmpty() {
   return head == NULL;
}
 
int length() {
   int length = 0;
   struct node *current;
 
   for(current = head; current != NULL; current = current->next) {
      length++;
   }
 
   return length;
}
 
//find a link with given key
struct node* find(int key) {
 
   //start from the first link
   struct node* current = head;
 
   //if list is empty
   if(head == NULL) {
      return NULL;
   }
 
   //navigate through list
   while(current->key != key) {
 
      //if it is last node
      if(current->next == NULL) {
         return NULL;
      } else {
         //go to next link
         current = current->next;
      }
   }      
 
   //if data found, return the current Link
   return current;
}
 
//delete a link with given key
struct node* delete(int key) {
 
   //start from the first link
   struct node* current = head;
   struct node* previous = NULL;
 
   //if list is empty
   if(head == NULL) {
      return NULL;
   }
 
   //navigate through list
   while(current->key != key) {
 
      //if it is last node
      if(current->next == NULL) {
         return NULL;
      } else {
         //store reference to current link
         previous = current;
         //move to next link
         current = current->next;
      }
   }
 
   //found a match, update the link
   if(current == head) {
      //change first to point to next link
      head = head->next;
   } else {
      //bypass the current link
      previous->next = current->next;
   }    
 
   return current;
}
 
void sort() {
 
   int i, j, k, tempKey, tempData;
   struct node *current;
   struct node *next;
 
   int size = length();
   k = size ;
 
   for ( i = 0 ; i < size - 1 ; i++, k-- ) {
      current = head;
      next = head->next;
 
      for ( j = 1 ; j < k ; j++ ) {   
 
         if ( current->data > next->data ) {
            tempData = current->data;
            current->data = next->data;
            next->data = tempData;
 
            tempKey = current->key;
            current->key = next->key;
            next->key = tempKey;
         }
 
         current = current->next;
         next = next->next;
      }
   }   
}
 
void reverse(struct node** head_ref) {
   struct node* prev   = NULL;
   struct node* current = *head_ref;
   struct node* next;
 
   while (current != NULL) {
      next  = current->next;
      current->next = prev;   
      prev = current;
      current = next;
   }
 
   *head_ref = prev;
}
 
void main() {
   insertFirst(1,10);
   insertFirst(2,20);
   insertFirst(3,30);
   insertFirst(4,1);
   insertFirst(5,40);
   insertFirst(6,56); 
 
   printf("Original List: "); 
 
   //print list
   printList();
 
   while(!isEmpty()) {            
      struct node *temp = deleteFirst();
      printf("\nDeleted value:");
      printf("(%d,%d) ",temp->key,temp->data);
   }  
 
   printf("\nList after deleting all items: ");
   printList();
   insertFirst(1,10);
   insertFirst(2,20);
   insertFirst(3,30);
   insertFirst(4,1);
   insertFirst(5,40);
   insertFirst(6,56);
 
   printf("\nRestored List: ");
   printList();
   printf("\n");  
 
   struct node *foundLink = find(4);
 
   if(foundLink != NULL) {
      printf("Element found: ");
      printf("(%d,%d) ",foundLink->key,foundLink->data);
      printf("\n");  
   } else {
      printf("Element not found.");
   }
 
   delete(4);
   printf("List after deleting an item: ");
   printList();
   printf("\n");
   foundLink = find(4);
 
   if(foundLink != NULL) {
      printf("Element found: ");
      printf("(%d,%d) ",foundLink->key,foundLink->data);
      printf("\n");
   } else {
      printf("Element not found.");
   }
 
   printf("\n");
   sort();
 
   printf("List after sorting the data: ");
   printList();
 
   reverse(&head);
   printf("\nList after reversing the data: ");
   printList();
}

Hash Table

#include <stdio.h>
#include <stdlib.h>
 
#define SIZE 10
 
struct Node {
    int key;
    int value;
    struct Node* next;
};
 
struct Node* hashTable[SIZE];
 
int hashFunction(int key) {
    return key % SIZE;
}
 
void insert(int key, int value) {
    struct Node* newNode = (struct Node*)malloc(sizeof(struct Node));
    newNode->key = key;
    newNode->value = value;
    newNode->next = NULL;
 
    int index = hashFunction(key);
 
    if (hashTable[index] == NULL) {
        hashTable[index] = newNode;
    } else {
        struct Node* current = hashTable[index];
        while (current->next != NULL) {
            current = current->next;
        }
        current->next = newNode;
    }
}
 
int search(int key) {
    int index = hashFunction(key);
 
    struct Node* current = hashTable[index];
    while (current != NULL) {
        if (current->key == key) {
            return current->value;
        }
        current = current->next;
    }
 
    return -1;
}
 
int main() {
    // Initialisierung der Hash-Tabelle
    for (int i = 0; i < SIZE; i++) {
        hashTable[i] = NULL;
    }
 
    // Einfügen von Elementen
    insert(1, 10);
    insert(2, 20);
    insert(11, 30);
 
    // Suche nach einem Schlüssel
    int value = search(2);
    if (value != -1) {
        printf("Value found: %d\n", value);
    } else {
        printf("Value not found.\n");
    }
 
    return 0;
}

Stack

#include <stdio.h>
#include <stdlib.h>
 
#define MAX_SIZE 100
 
struct Stack {
    int items[MAX_SIZE];
    int top;
};
 
void initialize(struct Stack* stack) {
    stack->top = -1;
}
 
int isEmpty(struct Stack* stack) {
    return stack->top == -1;
}
 
int isFull(struct Stack* stack) {
    return stack->top == MAX_SIZE - 1;
}
 
void push(struct Stack* stack, int item) {
    if (isFull(stack)) {
        printf("Stack overflow!\n");
        return;
    }
 
    stack->items[++stack->top] = item;
}
 
int pop(struct Stack* stack) {
    if (isEmpty(stack)) {
        printf("Stack underflow!\n");
        return -1;
    }
 
    return stack->items[stack->top--];
}
 
int main() {
    struct Stack stack;
    initialize(&stack);
 
    push(&stack, 1);
    push(&stack, 2);
    push(&stack, 3);
 
    printf("Popped: %d\n", pop(&stack));
    printf("Popped: %d\n", pop(&stack));
    printf("Popped: %d\n", pop(&stack));
 
    return 0;
}

Queue

#include <stdio.h>
#include <stdlib.h>
 
#define MAX_SIZE 100
 
struct Queue {
    int items[MAX_SIZE];
    int front;
    int rear;
};
 
void initialize(struct Queue* queue) {
    queue->front = -1;
    queue->rear = -1;
}
 
int isEmpty(struct Queue* queue) {
    return queue->front == -1;
}
 
int isFull(struct Queue* queue) {
    return (queue->rear + 1) % MAX_SIZE == queue->front;
}
 
void enqueue(struct Queue* queue, int item) {
    if (isFull(queue)) {
        printf("Queue overflow!\n");
        return;
    }
 
    if (isEmpty(queue)) {
        queue->front = 0;
        queue->rear = 0;
    } else {
        queue->rear = (queue->rear + 1) % MAX_SIZE;
    }
 
    queue->items[queue->rear] = item;
}
 
int dequeue(struct Queue* queue) {
    if (isEmpty(queue)) {
        printf("Queue underflow!\n");
        return -1;
    }
 
    int item = queue->items[queue->front];
    if (queue->front == queue->rear) {
        queue->front = -1;
        queue->rear = -1;
    } else {
        queue->front = (queue->front + 1) % MAX_SIZE;
    }
 
    return item;
}
 
int main() {
    struct Queue queue;
    initialize(&queue);
 
    enqueue(&queue, 1);
    enqueue(&queue, 2);
    enqueue(&queue, 3);
 
    printf("Dequeued: %d\n", dequeue(&queue));
    printf("Dequeued: %d\n", dequeue(&queue));
    printf("Dequeued: %d\n", dequeue(&queue));
 
    return 0;
}

Signed unsigned

By default an (ANSI C) integer is signed.

int a = 5;
int b = -10;
(a>b) ? puts("a>b") : puts("-");
 
unsigned int c = 5;
int d = -10;
(c>d) ? puts("c>d") : puts("-");
 
printf("%08x %08x %08x %08x", a,b,c,d);

Makros

#define f(a,b) a##b // strcat
#define h(a) g(a)   // exec
#define g(a) #a     // stringify

int main() {
    printf("%s\n",h(f(1,2)));
    printf("%s\n",g(f(1,2)));
    return 0;
}

Preprocessing

Gilt auch für CPP. Compileranweisungen vor dem eigentlichen Kompilierung ausführen. Dabei werden z.B makros durch den eigentlichen Code ersetzt.

Das folgende Programm mit gcc -E vorkompiliert

#define DEFINE_LL_NODE(CONCRETE_TYPE) \
    struct node_of_ ## CONCRETE_TYPE { \
        CONCRETE_TYPE data; struct node_of_ ## CONCRETE_TYPE *next; \
    }; \
       
#define DECLARE_LL_NODE(CONCRETE_TYPE, VARIABLE_NAME) \
    struct node_of_ ## CONCRETE_TYPE VARIABLE_NAME;
 
/* Declarations for types int and char  */
DEFINE_LL_NODE(int)
DEFINE_LL_NODE(char)
 
int main (void)
{
  /* Declaration of instances of each type.  */
  DECLARE_LL_NODE (int, foo)
  DECLARE_LL_NODE (char, bar)
 
  /* And you can then use these instances.  */
  foo.data = 1;
  foo.next = NULL;
 
  bar.data = 'c';
  bar.next = NULL;  
 
}

erzeugt ein Object file das so aussieht.

# 1 "main.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "main.c"
# 10 "main.c"
struct node_of_int { int data; struct node_of_int *next; };
struct node_of_char { char data; struct node_of_char *next; };
 
int main (void)
{
 
  struct node_of_int foo;
  struct node_of_char bar;
 
 
  foo.data = 1;
  foo.next = NULL;
 
  bar.data = 'c';
  bar.next = NULL;
 
}

Stdarg

Pass multiple (unknown at runtime) parameters to a function.

#include <stdarg.h>
 
// define known parameters, everything after ",..." must be the same Datatype!!!
void myfunc(const char *str, ...) {
   va_list list;
   va_start(list, str); 
   while(str) {
        printf("%s", str);
        str = va_arg(list, const char *);
   }
   va_end(list);
}
 
int main() {
    char *a = "a";
    char *b = "b";
    myfunc(a,b,NULL);
}

Classes

typedef struct Class Class;
 
struct Class {
    double width, height; /* Variables */
    double (*area)(Class *_class); /* Function pointer */
};
 
/* Function */
double calc(Class *_class) {
    return _class->width * _class->height;
}
 
/* Constructor */
Class _Class() {
    Class s;
    s.width = 1;
    s.height = 1;
    s.area = calc;
    return s;
}
 
int main() {
    Class s1 = _Class();
 
    s1.width = 4;
    s1.height = 5;
 
    printf("width = %f\n", s1.width);
    printf("height = %f\n", s1.height);
    printf("area = %f\n", s1.area(&s1));
 
};
#include <stdio.h>
 
typedef struct {
    void (*someMethod)(void);
} Test;
 
void hello(void) {
    printf("hello");
}
 
void world(void) {
    printf("world");
}
 
int main(void) {
    Test test;
    test.someMethod = "hello";
    test.someMethod();
    test.someMethod = "world";
    test.someMethod();
}

See also classes in CPP

Inline Assembly

GCC

#include <stdio.h>
 
int main() {
    int a = 5, b = 10, result;
 
    asm volatile (
        "movl %1, %%eax;"   // Move a into EAX register
        "movl %2, %%ebx;"   // Move b into EBX register
        "addl %%ebx, %%eax;"   // Add EBX to EAX
        "movl %%eax, %0;"   // Move the result back to variable result
        : "=r" (result)   // Output operand
        : "r" (a), "r" (b)   // Input operands
        : "%eax", "%ebx"   // Clobbered registers
    );
 
    printf("Result: %d\n", result);
 
    return 0;
}

Visual C++

#include <stdio.h>
 
int main() {
    int a = 5, b = 10, result;
 
    __asm {
        mov eax, a   // Move a into EAX register
        mov ebx, b   // Move b into EBX register
        add eax, ebx   // Add EBX to EAX
        mov result, eax   // Move the result back to variable result
    }
 
    printf("Result: %d\n", result);
 
    return 0;
}

Extended inline ASM

Resources

Datei resource.rc erstellen

#ifndef RESOURCE_RC_INCLUDED
#define RESOURCE_RC_INCLUDED
MAINICON  ICON  "icon.ico"
#endif

und

windres resource.rc resource.o

aufrufen.

Optional, in C/CPP nochmal definieren

#define MAINICON 101

Danach kann man das Programm wie üblich kompilieren.

gcc prog.c resource.o -o prog.exe

Processes

#include <stdio.h>
int main(int argc, char *argv[]) {    
    FILE *fp = popen("ipconfig", "w");
    int i = 0;
    char line[1024];    
    while (fgets(line, sizeof(line), fp) != NULL) {
        printf("%s\n", line);
    }        
    pclose(fp);
    return 0;
}

Signal

#include <signal.h>
void catch_function(int sig) {
    exit(EXIT_FAILURE);
}
signal(SIGINT, catch_function);

declspec

extern "C"
{
 
    __declspec(dllexport) int add(int a,int b) {
        return a+b;
    }
 
    __declspec(dllexport) int subtract(int a,int b) {
        return a-b;
    }
 
}

Libraries und Shared objects

// windows
__declspec(dllexport) char *myfunc() {
    return "myfunc called";
}
 
// linux
__attribute__ ((visibility ("default"))) char *myfunc() {
    return "myfunc called";
}

Diese Library Datei kompiliert man mit dem -c Parameter.

// -fPIC für positionsunabhängigen Code

// Windows dynamic
gcc -c test.c -o test.o 
gcc -shared test.o -o test.dll
gcc main.c -o main -L. -ljail

// Windows static
gcc -c -static test.c 
ar rcs test.a test.o
gcc main.c -o main test.a 

// Linux dynamic
gcc -c test.c 
gcc -shared test.o -o libTest.so // with lib prefix
gcc main.c -o main -L. -lTest // without lib prefix

// Linux static
gcc -c test.c -o test.o
ar crf libTest.a test.o // with lib prefix
gcc main.c -o main -L. -lTest // without lib prefix
#include <stdio.h>
#include <string.h>
 
#ifdef _WIN32
#include <windows.h>
#else
#include <dlfcn.h>
#endif
 
#ifdef _WIN32
typedef HANDLE lib_t;
#else
typedef void* lib_t;
#endif
 
lib_t MyLoadLib(const char* lib) {
    #ifdef _WIN32
    return LoadLibraryA(lib);
    #else 
    return dlopen(lib, RTLD_LAZY);
    #endif 
}
 
void MyUnloadLib(lib_t lib) {
    #ifdef _WIN32
    FreeLibrary(lib);
    #else 
    dlclose(lib);
    #endif 
}
 
void* MyLoadProc(lib_t lib, const char* proc) {
    #ifdef _WIN32
    return GetProcAddress(lib, proc);
    #else 
    return dlsym(lib, proc);
    #endif 
}
 
int main(int argc, char **argv) {
 
    lib_t myLib = NULL;
 
    myLib = MyLoadLib("./myLib.so"); 
 
    void *funcname;
    funcname = "init";
 
    void *(*func_ptr)() = MyLoadProc(myLib, funcname); 
 
    char *result;
    result = (*func_ptr)();
    printf("%s", result);
 
    MyUnloadLib(myLib);
 
    return 0;
 
}

More