Created
April 8, 2015 16:49
-
-
Save jendas1/0f06e55e4537fd7c9647 to your computer and use it in GitHub Desktop.
Snippets for better experience when working with C
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// There are some snippets I've found useful when programming in C. | |
// Author: Jan Studený | |
// | |
#include <stdio.h> | |
#define __STDC_FORMAT_MACROS // Enable printing (u)int(64,32,16,8)_t | |
#include <inttypes.h> | |
#define allocate_object(type) (type *) malloc(sizeof(type)) | |
#define allocate_array(length, type) (type *) malloc((length)*sizeof(type)) | |
#define allocate_fresh_array(length, type) (type *) calloc(length, sizeof(type)) | |
#define array_with_size(length, type) (type *) malloc((length)*sizeof(type) + len_cell_size(sizeof(type))) + len_cell_size(sizeof(type)) | |
#define array_size(array, type) (uint64_t *)(array + len_index(sizeof(type))) | |
#define reallocate_array(array, length, type) (type *) realloc((array), (length)*sizeof(type)) | |
//#TODO: add implementation | |
#define reallocate_fresh_array(array, old_length, new_length, type) do { \ | |
\ | |
} while (0) | |
#if defined(DEBUG) | |
#define debug_print(a) puts(a) | |
#define printf_debug(a) printf(a) | |
#else | |
#define printf_debug(a) | |
#define debug_print(a) | |
#endif | |
#define PRINT_INVALID_INPUT puts("Invalid input.") | |
#define INVALID_INPUT PRINT_INVALID_INPUT; return -1 | |
#define MyLinkedList(T) typedef struct LListElement_ ## T LListElement_ ## T; \ | |
struct LListElement_ ## T \ | |
{ \ | |
T value; \ | |
LListElement_ ## T * next; \ | |
}; | |
#ifndef __REDIRECT_INPUT__ | |
#define __REDIRECT_INPUT__ | |
void redirect_input(const char * filename) { | |
freopen(filename, "r", stdin); | |
} | |
#endif | |
/********************************************************************** | |
* | |
* List - Simple auto-expansible array of pointers | |
* Author: Alberto Ferreira | |
* | |
* Use it to store collections of any type of variable | |
* | |
* Release Date: 27Jan2011 | |
* License: GPLv2 | |
* | |
* Thanks to Trinidad @ Stack Overflow | |
* | |
*********************************************************************/ | |
/* list->items; // pointers to all assigned items -- ITEMS ARE NOT ALLOCATED, DO THAT YOURSELF, ONLY THEIR POINTER IS COPIED INTO HERE | |
* | |
* */ | |
/* Usage: | |
* 1 - First define the type of variable you want it to be available to - ONLY DO IT ONCE: | |
* | |
* List(float); // variable type. You will have to use it after "List_" to use the proper type of list | |
* | |
* 2 - Create a pointer and initiate a list to work with | |
* | |
* List_float *l1; | |
* l1 = List_float_init(); | |
* | |
* | |
* | |
* 3 - It's done, you can add and remove entries! | |
* (the order of the entries is the order of insertion) | |
* | |
* int a = 4; | |
* | |
* List_add (l1, &a); | |
* | |
* | |
* */ | |
// consider mantaining custom_free!!!!!!!!!!!!!!!!!!! | |
#define List(T) typedef struct { \ | |
T** items; \ | |
int last_item_index; \ | |
int size; /*number of currently allocated elements*/ \ | |
int capacity; /* >= #elements so that we don't have to always call malloc */ \ | |
/*size_t element_size; */ /* Unused variable */ \ | |
void (*custom_free)(T *); \ | |
} List_ ## T; \ | |
\ | |
int List_ ## T ## _realloc (List_ ## T *list) { \ | |
T ** tmp_entries = NULL; \ | |
int i; \ | |
list->capacity *=2; \ | |
tmp_entries = (T **) realloc (list->items, sizeof(T*)*list->capacity); \ | |
if (tmp_entries == NULL) return 0; \ | |
else list->items = tmp_entries; \ | |
for (i=list->size; i < list->capacity; i++) { \ | |
list->items[i] = (T*) NULL; \ | |
} \ | |
return 1; \ | |
} \ | |
\ | |
List_ ## T * List_ ## T ## _init() { \ | |
List_ ## T * list = allocate_object(List_ ## T); \ | |
list->items = allocate_fresh_array(2, T *); \ | |
list->size = 0; \ | |
list->capacity = 2; \ | |
list->last_item_index=-1; \ | |
list->custom_free = NULL; \ | |
return list; \ | |
} \ | |
\ | |
int List_ ## T ## _add (List_ ## T *list, T *address) { \ | |
if (list->size == list->capacity) { \ | |
List_ ## T ## _realloc(list); \ | |
} \ | |
list->items[list->last_item_index+1] = address; \ | |
list->last_item_index++; \ | |
list->size++; \ | |
return 1; \ | |
} \ | |
void List_ ## T ## _free (List_ ## T *list) { \ | |
for (int i = 0; i< list->size; i++) { \ | |
if (list->custom_free != NULL) { \ | |
list->custom_free(list->items[i]); \ | |
} \ | |
else { \ | |
free(list->items[i]); \ | |
} \ | |
} \ | |
free(list->items); \ | |
free (list); \ | |
} | |
//Unused functions | |
/* | |
//void List_ ## T ## _compress (List_ ## T *list) { \ | |
// int i, i2; \ | |
// for (i=0; i < list->size - 1; ++i) { \ | |
// if (list->items[i] == NULL) //found an empty { | |
// for (i2 = i+1; i2 < list->size && list->items[i2] == NULL; ++i2); \ | |
// //empty for - stop on first non-empty list->items[i] = list->items[i2]; \ | |
// list->items[i2] = (T*)NULL; \ | |
// } | |
// list->last_item_index = list->elements - 1; \ | |
//} \ | |
//void List_ ## T ## _del (List_ ## T *list, unsigned int pos) { if (pos>=list->size) return; \ | |
// free(list->items[pos]); \ | |
// list->items[pos] = NULL; \ | |
// --list->elements; \ | |
// if (pos == list->last_item_index) { int p=pos; \ | |
// while (list->items[p]) --p; \ | |
// list->last_item_index = p; \ | |
// } } \ | |
*/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment