Skip to content

Instantly share code, notes, and snippets.

@keegoo
Last active February 17, 2020 03:17
Show Gist options
  • Save keegoo/6349c5aab2672b0a2d2d54838d79a5e9 to your computer and use it in GitHub Desktop.
Save keegoo/6349c5aab2672b0a2d2d54838d79a5e9 to your computer and use it in GitHub Desktop.
// --------------- catalog ---------------
//
// * basic data type and size(64-bit platforms)
// * padding for alignment requirements
// * a useful function to print number in binary
// * pointer and double pointer
// * printf
// * struct
// * initialize and access
// * access through pointer
// * nested struct and access
// * stack vs heap
// * function pointer & callback function
// * typedef function pointer
// * initialize and iterate linked nodes
// ########## ########## ########## ##########
// ## basic data type and size(64-bit platforms)
#include <stdio.h>
int main()
{
// char: 1 byte
printf("char: %d bytes\n", sizeof(char));
printf("unsigned char: %d bytes\n", sizeof(unsigned char));
printf("signed char: %d bytes\n", sizeof(signed char));
// int: 4 bytes
printf("int: %d bytes\n", sizeof(int));
printf("unsigned int: %d bytes\n", sizeof(unsigned int));
// short: 2 bytes
printf("short: %d bytes\n", sizeof(short));
printf("unsigned short: %d bytes\n", sizeof(unsigned short));
// long: 8 bytes
printf("long: %d bytes\n", sizeof(long));
printf("unsigned int: %d bytes\n", sizeof(unsigned long));
// float: 4 bytes
printf("float: %d bytes\n", sizeof(float));
// double: 8 bytes
printf("double: %d bytes\n", sizeof(double));
// void: 1 byte
printf("void: %d byte\n", sizeof(void));
// pointer: all pointers are 8 bytes
printf("char*: %d bytes\n", sizeof(char*));
printf("int*: %d bytes\n", sizeof(int*));
printf("short*: %d bytes\n", sizeof(short*));
printf("long*: %d bytes\n", sizeof(long*));
printf("float*: %d bytes\n", sizeof(float*));
printf("double*: %d bytes\n", sizeof(double*));
printf("void*: %d bytes\n", sizeof(void*));
return 0;
}
// *** padding for alignment requirements
//
// in my case(depends on your compiler):
// when there's single type in struct, no padding.
// when there's multiple types in struct, will padding to 8 bytes.
struct A {
char ch;
};
struct B {
char ch;
int i;
};
struct C {
char ch[9];
};
struct D {
char ch[9];
int i;
void* pointer;
};
sizeof(struct A); // -> 1 byte
sizeof(struct B); // -> 8 bytes, as `1 + 4 < 8` then padding to 8 bytes
sizeof(struct C); // -> 9 bytes
sizeof(struct D); // -> 24 bytes, as `9 + 4 + 8 < 24` then padding to 24 bytes
// the variables defined by struct A, B, C or D has the same size as their type.
struct A a; sizeof(a); // -> 1 byte
struct B b; sizeof(b); // -> 8 bytes
struct C c; sizeof(c); // -> 9 bytes
struct D d; sizeof(d); // -> 24 bytes
// *** a useful function to print number in binary
#include <stdio.h>
void print_bits(size_t const size, void const * const ptr)
{
unsigned char *b = (unsigned char*) ptr;
unsigned char byte;
int i, j;
for (i = size - 1; i >= 0; i--)
{
for (j = 7; j >= 0; j--)
{
byte = (b[i] >> j) & 1;
printf("%u", byte);
}
}
printf("\n");
}
int main(int argv, char* argc[])
{
int i = 23;
float f = 23.45f;
long z = 3456;
print_bits(sizeof(i), &i); // 00000000000000000000000000010111
print_bits(sizeof(f), &f); // 01000001101110111001100110011010
print_bits(sizeof(z), &z); // 0000000000000000000000000000000000000000000000000000110110000000
return 0;
}
// ########## ########## ########## ##########
// ## pointer and double pointer
#include <stdio.h>
int main()
{
int num = 123;
int* pr2;
int** pr1;
pr2 = &num;
pr1 = &pr2;
/* Possible ways to find value of variable num*/
printf("Value of num is: %d\n", num);
printf("Value of num using pr2 is: %d\n", *pr2);
printf("Value of num using pr1 is: %d\n", **pr1);
/*Possible ways to find address of num*/
printf("Address of num is: %p\n", &num);
printf("Address of num using pr2 is: %p\n", pr2);
printf("Address of num using pr1 is: %p\n", *pr1);
/*Find value of pointer*/
printf("Value of Pointer pr2 is: %p\n", pr2);
printf("Value of Pointer pr2 using pr1 is: %p\n", *pr1);
/*Ways to find address of pointer*/
printf("Address of Pointer pr2 is: %p\n", &pr2);
printf("Address of Pointer pr2 using pr1 is: %p\n", pr1);
/*Double pointer value and address*/
printf("Value of Pointer pr1 is: %p\n", pr1);
printf("Address of Pointer pr1 is: %p\n", &pr1);
/* true */
num == *pr2; *pr2 == **pr1;
&num == pr2; pr2 == *pr1;
&pr2 == pr1;
return 0;
}
// ########## ########## ########## ##########
// printf
int i = 0;
float f = 0.1;
double d = 0.2;
printf("int %d\n", i);
printf("float %f\n", f);
printf("double %f\n", d);
printf("address %p\n", &i);
// ########## ########## ########## ##########
// ## struct
// *** initialize and access
#include <stdio.h>
struct Books {
char title[50];
char author[50];
int id;
};
int main() {
struct Books b1 = {"C Programming", "Nuha Ali", 123456};
printf("Book 1 title : %s\n", b1.title);
printf("Book author : %s\n", b1.author);
printf("Book 1 id: %d\n", b1.id);
return(0);
}
// *** access through pointer
void print_book(struct Books *book) {
printf("Book title : %s\n", book->title);
printf("Book author : %s\n", book->author);
printf("Book id : %d\n", book->id);
}
int main() {
struct Books b1 = {"C Programming", "Nuha Ali", 123456};
print_book(&b1);
return(0);
}
// *** nested struct and access
#include <stdio.h>
struct Author {
char first[50];
char last[50];
};
struct Books {
char title[50];
struct Author author;
int id;
};
void print_book(struct Books *book) {
printf("Book title : %s\n", book->title);
printf("Book author : %s\n", book->author.first);
printf("Book id : %d\n", book->id);
}
int main() {
struct Books b1 = {"C Programming", {"Nuha", "Ali"}, 123456};
printf("Book 1 title : %s\n", b1.title);
printf("Book author : %s\n", b1.author.first);
printf("Book 1 id: %d\n", b1.id);
print_book(&b1);
return(0);
}
// ########## ########## ########## ##########
// ## stack vs heap
// *** stack
#include <stdio.h>
double multiplyByTwo (double input) {
double twice = input * 2.0;
return twice;
}
int main (int argc, char *argv[])
{
int age = 30;
double salary = 12345.67;
double myList[3] = {1.2, 2.3, 3.4};
printf("double your salary is %.3f\n", multiplyByTwo(salary));
return 0;
}
// *** heap
#include <stdio.h>
#include <stdlib.h>
double *multiplyByTwo (double *input) {
double *twice = malloc(sizeof(double));
*twice = *input * 2.0;
return twice;
}
int main (int argc, char *argv[])
{
int *age = malloc(sizeof(int));
*age = 30;
double *salary = malloc(sizeof(double));
*salary = 12345.67;
double *myList = malloc(3 * sizeof(double));
myList[0] = 1.2;
myList[1] = 2.3;
myList[2] = 3.4;
double *twiceSalary = multiplyByTwo(salary);
printf("double your salary is %.3f\n", *twiceSalary);
free(age);
free(salary);
free(myList);
free(twiceSalary);
return 0;
}
// ########## ########## ########## ##########
// ## function pointer & callback function
// *** function pointer
#include <stdio.h>
void fun(int a) { printf("Value of a is %d\n", a); }
int main()
{
// fun_ptr is a pointer to function fun()
void (*fun_ptr)(int) = &fun;
// Invoking fun() using fun_ptr
(*fun_ptr)(10);
return 0;
}
// *** callbacks
#include <stdio.h>
void fun1(int a) {printf("fun1 and %d\n", a);}
void fun2(int a) {printf("fun2 and %d\n", a);}
void wrapper(void (*fun)(int))
{
fun(10);
}
int main()
{
wrapper(fun1);
wrapper(fun2);
return 0;
}
// ########## ########## ########## ##########
// ## typedef function pointer
// compare with previous example
#include <stdio.h>
void fun1(int a) {printf("fun1 and %d\n", a);}
void fun2(int a) {printf("fun2 and %d\n", a);}
// define the new pattern `void identifier(int)` as a type `for_fun`
typedef void (*for_fun)(int);
void wrapper(for_fun fun)
{
fun(10);
}
int main()
{
wrapper(fun1);
wrapper(fun2);
return 0;
}
// ########## ########## ########## ##########
// ## initialize and iterate linked nodes
#include <stdio.h>
#include <stdlib.h>
typedef struct Node* NodePtr;
struct Node {
struct Node* next;
int id;
};
NodePtr append(NodePtr n) {
NodePtr res = malloc(sizeof(*res));
res->next = n;
res->id = rand();
return res;
}
int main() {
// initialize head
NodePtr head = malloc(sizeof(*head));
head->next = NULL;
head->id = 0;
// chain Nodes with append()
int i;
for(i = 0; i < 10; i ++)
head = append(head);
// iterate and print
NodePtr current = head;
while(1) {
printf("%d\n", current->id);
current = current->next;
if(current == NULL) { break; }
}
return(0);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment