Learning by doing: Reading books and trying to understand the (code) examples
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

351 lines
9.7 KiB

  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <string.h>
  4. void displayArray(int arr[], size_t size);
  5. void displayArrayPtr(int *arr, size_t size);
  6. int safeCompare(const void *a, const void *b, size_t asize, size_t bsize);
  7. int valid(void *p);
  8. void display2DArray(int arr[][5], size_t rows);
  9. void display2DArrayPtr(int (*arr)[5], size_t rows);
  10. void display2DArrayUnknownSize(int *arr, size_t rows, size_t cols);
  11. void display3DArrayPtr(int (*arr)[2][4], size_t rows);
  12. void displayArray(int arr[], size_t size) {
  13. for (size_t i = 0; i < size; i++) {
  14. // both variants are possible
  15. printf("%d\n", arr[i]);
  16. //printf("%d\n", *(arr + i));
  17. }
  18. }
  19. void displayArrayPtr(int *arr, size_t size) {
  20. for (size_t i = 0; i < size; i++) {
  21. // both variants are possible
  22. printf("%d\n", *(arr + i));
  23. //printf("%d\n", arr[i]);
  24. }
  25. }
  26. int safeCompare(const void *a, const void *b, size_t asize, size_t bsize) {
  27. if (asize != bsize) {
  28. return -1;
  29. }
  30. int value = 0;
  31. for (size_t i = 0; i < asize; i++) {
  32. //value |= a[i] ^ b[i];
  33. value |= ((unsigned char*) a)[i] ^ ((unsigned char*) b)[i];
  34. }
  35. return value;
  36. }
  37. void display2DArray(int arr[][5], size_t rows) {
  38. for (size_t i = 0; i < rows; i++) {
  39. for (size_t j = 0; j < 5; j++) {
  40. printf("%d", arr[i][j]);
  41. }
  42. printf("\n");
  43. }
  44. }
  45. void display2DArrayPtr(int (*arr)[5], size_t rows) {
  46. for (size_t i = 0; i < rows; i++) {
  47. for (size_t j = 0; j < 5; j++) {
  48. printf("%d", *(arr[i] + j));
  49. }
  50. printf("\n");
  51. }
  52. }
  53. void display2DArrayUnknownSize(int *arr, size_t rows, size_t cols) {
  54. for (size_t i = 0; i < rows; i++) {
  55. for (size_t j = 0; j < cols; j++) {
  56. // both are equivalent
  57. //printf("%d", *(arr + (i * cols) + j));
  58. printf("%d", (arr + (i * cols))[j]);
  59. }
  60. printf("\n");
  61. }
  62. }
  63. void display3DArrayPtr(int (*arr)[2][4], size_t rows) {
  64. for (size_t i = 0; i < rows; i++) {
  65. for (size_t j = 0; j < 2; j++) {
  66. printf("{");
  67. for (size_t k = 0; k < 4; k++) {
  68. printf("%d", arr[i][j][k]);
  69. if (k != 3) {
  70. printf(" ");
  71. }
  72. }
  73. printf("}");
  74. }
  75. printf("\n");
  76. }
  77. }
  78. int main(void) {
  79. int vector[5] = {1,2,3,4,5};
  80. printf("length of vector: %zu\n", sizeof(vector)/sizeof(int));
  81. int matrix[2][3] = {{1,2,3},{4,5,6}};
  82. for (size_t index = 0; index < 2; index++) {
  83. printf("&matrix[%zu]: %p sizeof(matrix[%zu]): %zu\n",
  84. index, &matrix[index], index, sizeof(matrix[index]));
  85. }
  86. // pointer notation and arrays
  87. {
  88. int *pv = vector;
  89. int value = 3;
  90. for (size_t index = 0; index < sizeof(vector)/sizeof(int); index++) {
  91. // all following operations are equivalent
  92. *pv++ *= value;
  93. //pv[index] *= value;
  94. //*(pv + index) *= value;
  95. //vector[index] *= value;
  96. }
  97. for (size_t index = 0; index < sizeof(vector)/sizeof(int); index++) {
  98. printf("vector[%zu]: %d\n", index, vector[index]);
  99. }
  100. }
  101. // using malloc to create a one-dimensional array
  102. {
  103. int *pv = malloc(5 * sizeof(*pv));
  104. for (size_t i = 0; i < 5; i++) {
  105. pv[i] = i + 1;
  106. }
  107. for (size_t i = 0; i < 5; ++i) {
  108. *(pv + i) = i + 1;
  109. }
  110. for(size_t index = 0; index < 5; index++) {
  111. printf("pv[%zu]: %d\n", index, pv[index]);
  112. }
  113. free(pv);
  114. }
  115. // passing array to function using array notation
  116. displayArray(vector, sizeof(vector)/sizeof(int));
  117. // passing array to function using pointer notation
  118. displayArrayPtr(vector, sizeof(vector)/sizeof(int));
  119. // using a one-dimensional array of pointers
  120. {
  121. int *arr[5];
  122. for (size_t i = 0; i < 5; i++) {
  123. // both variants are equivalent
  124. arr[i] = malloc(sizeof(arr[i]));
  125. *arr[i] = i;
  126. //arr[i][0] = i;
  127. //*(arr + i) = (int*) malloc(sizeof(int));
  128. //**(arr + i) = i;
  129. printf("%d\n", **(arr + i));
  130. }
  131. for (size_t i = 0; i < 5; i++) {
  132. free(arr[i]);
  133. }
  134. }
  135. // pointers and multidimensional arrays
  136. {
  137. // declare a 2-dimensional array
  138. int matrix[2][5] = {{1, 2, 3, 4, 5}, {6, 7, 8, 9, 10}};
  139. for (size_t i = 0; i < 2; i++) {
  140. for (size_t j = 0; j < 5; j++) {
  141. printf("matrix[%zu][%zu] Address: %p Value %d\n", i, j, &matrix[i][j], matrix[i][j]);
  142. }
  143. }
  144. // declare a pointer to a 2-dimensional array
  145. int (*pmatrix)[5] = matrix;
  146. // 1st row
  147. printf("%p\n", matrix);
  148. // 2nd row
  149. printf("%p\n", matrix + 1);
  150. // size of 1st row
  151. printf("sizeof(matrix[0]): %zu\n", sizeof(matrix[0]));
  152. // access 2nd element
  153. printf("%p %d\n", matrix[0] + 1, *(matrix[0] + 1));
  154. }
  155. // passing a multidimensional array
  156. {
  157. // declare a 2-dimensional array
  158. int matrix[2][5] = {{1, 2, 3, 4, 5}, {6, 7, 8, 9, 10}};
  159. display2DArray(matrix, 2);
  160. display2DArrayPtr(matrix, 2);
  161. display2DArrayUnknownSize(&matrix[0][0],
  162. sizeof(matrix) / sizeof(matrix[0]),
  163. sizeof(matrix[0]) / sizeof(*matrix[0]));
  164. int arr3D[][2][4] = {
  165. {{1, 2, 3, 4}, {5, 6, 7, 8}},
  166. {{9, 10, 11, 12}, {13, 14, 15, 16}},
  167. {{17, 18, 19, 20}, {21, 22, 23, 24}}
  168. };
  169. display3DArrayPtr(arr3D, 3);
  170. }
  171. // dynamically allocating a two-dimensional array
  172. {
  173. // allocating contigously memory
  174. int matrix[2][5] = {{1, 2, 3, 4, 6}, {6, 7, 8, 9, 10}};
  175. for (size_t i = 0; i < 2; i++) {
  176. for (size_t j = 0; j < 5; j++) {
  177. printf("matrix[%zu][%zu] Address: %p Value: %d\n", i, j, &matrix[i][j], matrix[i][j]);
  178. }
  179. printf("\n");
  180. }
  181. // allocating potential noncontiguous memory
  182. {
  183. size_t rows = 2;
  184. size_t cols = 5;
  185. int **matrix = malloc(rows * sizeof(int *));
  186. for (size_t i = 0; i < rows; i++) {
  187. matrix[i] = malloc(cols * sizeof(int));
  188. }
  189. free(matrix);
  190. }
  191. // allocating contiguous memory
  192. {
  193. size_t rows = 2;
  194. size_t cols = 5;
  195. int **matrix = malloc(rows * sizeof(int*));
  196. matrix[0] = malloc(rows * cols * sizeof(int));
  197. for (size_t i = 1; i < rows; i++) {
  198. matrix[i] = matrix[0] + i * cols;
  199. }
  200. free(matrix);
  201. }
  202. // allocating contiguous memory
  203. {
  204. size_t rows = 2;
  205. size_t cols = 5;
  206. int *matrix = malloc(rows * cols * sizeof(int));
  207. for (size_t i = 0; i < rows; i++) {
  208. for (size_t j = 0; j < cols; j++) {
  209. *(matrix + (i * cols) + j) = i * j;
  210. }
  211. }
  212. free(matrix);
  213. }
  214. // jagged arrays and pointers
  215. {
  216. // 2 dimensional array with compound literals
  217. int *arr1[] = {
  218. (int[]) {0, 1, 2},
  219. (int[]) {3, 4, 5},
  220. (int[]) {6, 7, 8}
  221. };
  222. for (size_t i = 0; i < 3; i++) {
  223. for (size_t j = 0; j < 3; j++) {
  224. printf("arr1[%zu][%zu] Address: %p Value: %d\n", i, j, &arr1[i][j], arr1[i][j]);
  225. }
  226. printf("\n");
  227. }
  228. // 2 dimensinal jagged array with compound literals
  229. int *arr2[] = {
  230. (int[]) {0, 1, 2, 3},
  231. (int[]) {4, 5},
  232. (int[]) {6, 7, 8}
  233. };
  234. for (size_t i = 0; i < 4; i++) {
  235. printf("arr2[0][%zu] Address: %p Value: %d\n", i, &arr2[0][i], *(arr2[0] + i));
  236. }
  237. printf("\n");
  238. for (size_t i = 0; i < 2; i++) {
  239. printf("arr2[1][%zu] Address: %p Value: %d\n", i, &arr2[1][i], *(arr2[1] + i));
  240. }
  241. printf("\n");
  242. for (size_t i = 0; i < 3; i++) {
  243. printf("arr2[2][%zu] Address: %p Value: %d\n", i, &arr2[2][i], arr2[2][i]);
  244. }
  245. printf("\n");
  246. }
  247. }
  248. // test safeCompare function
  249. {
  250. // test with char parameters
  251. char a[] = "wurst";
  252. char b[] = "wurst";
  253. if(safeCompare(a, b, sizeof(a), sizeof(b))) {
  254. printf("%s ungleich %s\n", a, b);
  255. } else {
  256. printf("%s gleich %s\n", a, b);
  257. }
  258. // test with int parameters
  259. int bla[] = {0,1,2,3,4};
  260. int bli[] = {0,1,2,3,4};
  261. if(safeCompare(bla, bli, sizeof(bla), sizeof(bli))) {
  262. printf("%s ungleich %s\n", "bla", "bli");
  263. } else {
  264. printf("%s gleich %s\n", "bla", "bli");
  265. }
  266. // test with unsigned char parameters
  267. unsigned char blar[] = {0x00, 0x01, 0x02, 0x03, 0x04};
  268. unsigned char blir[] = {0x00, 0x01, 0x02, 0x03, 0x04};
  269. if(safeCompare(blar, blir, sizeof(blar), sizeof(blir))) {
  270. printf("%s ungleich %s\n", "blar", "blir");
  271. } else {
  272. printf("%s gleich %s\n", "blar", "blir");
  273. }
  274. // test with unsigned char
  275. unsigned char blab = 0x00;
  276. unsigned char blib = 0x01;
  277. if(safeCompare(&blab, &blib, sizeof(blab), sizeof(blib))) {
  278. printf("%s ungleich %s\n", "blar", "blir");
  279. } else {
  280. printf("%s gleich %s\n", "blar", "blir");
  281. }
  282. }
  283. return 0;
  284. }