C programming: frequent questions and test-approved answers
Submitted by st on
Q1. Difference between ++*p, *p++ and *++p
Priority to keep in mind:
- postfix ++
- prefix ++
- *
#include <stdio.h> int main() { int arr[] = {10, 20}; int *p1 = arr; int *p2 = arr; int *p3 = arr; printf("arr[0] = %d, arr[1] = %d\n", arr[0], arr[1]); printf("arr[0] = %d, arr[1] = %d, *++p1 = %d\n", arr[0], arr[1], *++p1); printf("arr[0] = %d, arr[1] = %d, *p2++ = %d\n", arr[0], arr[1], *p2++); printf("arr[0] = %d, arr[1] = %d, *p2 = %d\n", arr[0], arr[1], *p2); ++*p3; printf("++*p3\narr[0] = %d, arr[1] = %d, *p3 = %d\n", arr[0], arr[1], *p3); return 0; }
arr[0] = 10, arr[1] = 20 arr[0] = 10, arr[1] = 20, *++p1 = 20 arr[0] = 10, arr[1] = 20, *p2++ = 10 arr[0] = 10, arr[1] = 20, *p2 = 20 ++*p3 arr[0] = 11, arr[1] = 20, *p3 = 11
Q2. Deep and shallow copies (object oriented style)
#include <stdio.h> #include <stdlib.h> #include <string.h> typedef struct { char* first_name; char* last_name; int age; } person; person* person_create() { person* result = (person*)malloc(sizeof(person)); result->first_name = NULL; result->last_name = NULL; result->age = 0; return result; } void person_set_first_name(person* const self, const char* value) { if (self->first_name) free(self->first_name); size_t len = strlen(value) + 1; self->first_name = (char*)malloc(len); strcpy_s(self->first_name, len, value); } void person_set_last_name(person* const self, const char* value) { if (self->last_name) free(self->last_name); size_t len = strlen(value) + 1; self->last_name = (char*)malloc(len); strcpy_s(self->last_name, len, value); } person* person_create2(const char* first_name, const char* last_name, const int age) { person* self = person_create(); person_set_first_name(self, first_name); person_set_last_name(self, last_name); self->age = age; return self; } person* person_create_copy_shallow(const person* source) { person* self = person_create(); *self = *source; return self; } person* person_create_copy_deep(const person* source) { person* self = person_create(); person_set_first_name(self, source->first_name); person_set_last_name(self, source->last_name); self->age = source->age; return self; } void person_free(person** self) { if ((*self)->first_name) free((*self)->first_name); if ((*self)->last_name) free((*self)->last_name); free(*self); *self = NULL; } void person_print(const person* self, const char* title) { printf("%s:\n First name: %s\n Last name: %s\n Age: %d\n", title, self->first_name, self->last_name, self->age); } int main(void) { person *p1, *p2, *p3; const char* first_name1 = "John"; const char* first_name2 = "James"; const char* first_name3 = "Nathaniel"; p1 = person_create2(first_name1, "Smith", 35); person_print(p1, "P1"); p2 = person_create_copy_shallow(p1); person_print(p2, "P2 is a shallow copy of P1"); person_set_first_name(p1, first_name2); p1->age = 40; puts("P1 first name and age has changed"); person_print(p1, "P1"); person_print(p2, "P2 name has changed too"); p3 = person_create_copy_deep(p1); person_print(p3, "P3 is a deep copy of P1"); person_set_first_name(p1, first_name3); p1->age = 45; puts("P1 first name and age has changed again"); person_print(p1, "P1"); person_print(p3, "P3 stays unchanged"); person_free(&p1); free(p2); // Cannot use person_free(&p2) because of shallow coly person_free(&p3); return 0; }
P1: First name: John Last name: Smith Age: 35 P2 is a shallow copy of P1: First name: John Last name: Smith Age: 35 P1 first name and age has changed P1: First name: James Last name: Smith Age: 40 P2 name has changed too: First name: James Last name: Smith Age: 35 P3 is a deep copy of P1: First name: James Last name: Smith Age: 40 P1 first name and age has changed again P1: First name: Nathaniel Last name: Smith Age: 45 P3 stays unchanged: First name: James Last name: Smith Age: 40