#include <stdlib.h>
#include <stdio.h>

int a = 1;
int b = 2;


/**
 * compute (x+1) + (y+1)
 */
int sum_plus(int x, int *y) {
	x = x + 1; // or ++x
	*y = *y + 1; // or ++*y;
		
	return x + *y;
}


/**
 * structure that is used to compute z = x @ y
 * where @ = +, -, *, /, ...
 */
typedef struct {
	int x, y, z;
} Operation;

/**
 * execute sum on operation but call by value
 */
void operation_plus_by_value(Operation op) {
	op.z = op.x + op.y;
}

/**
 * execute sum on operation but call by address
 */
void operation_plus_by_address(Operation *op) {
	op->z = op->x + op->y;
}

/**
 * execute sum on operation but call by reference
 */
void operation_plus_by_reference(Operation& op) {
	// use the syntax of call by value
	op.z = op.x + op.y;
}


/**
 * main function
 */
int main() {
	int c;
	
	printf("before sum_plus\n");
	printf("a = %d\n", a);
	printf("b = %d\n", b);
	
	c = sum_plus(a, &b);
	
	printf("-------------\n");
	printf("after sum_plus\n");
	printf("a = %d\n", a);
	printf("b = %d\n", b);
	printf("c = %d\n", c);

	// example with structure
	Operation op1;
	op1.x = 1;	
	op1.y = 2;
	op1.z = 0;
	Operation op2 = op1;
		
	// call by value : KO, result won't be registered
	operation_plus_by_value(op1);
	printf("result of by value z = %d\n", op1.z);
	
	// call by address : OK
	operation_plus_by_address(&op1);
	printf("result of by address z = %d\n", op1.z);

	// call by reference : OK
	operation_plus_by_reference(op2);
	printf("result of by reference z = %d\n", op2.z);

	return 0;
}

