-
Notifications
You must be signed in to change notification settings - Fork 0
/
9 Functions.c
79 lines (67 loc) · 2.45 KB
/
9 Functions.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
#include <limits.h>
#include <stdlib.h>
#include <stdio.h>
// Same format as Java
/** Returns a `long` so it does not overflow. Though `unsigned`, the result never exceed `LONG_MAX`. */
unsigned long square(int number) {
return ((long)number) * number;
}
/* A programmer can use pointer params to
* Limit the immediate size of the args stack (e.g., when passing a collection)
* Ask for memory regions that the function can write to;
i.e., emulate output or in-out params, typically for multiple return values.
*/
/** `square` but using an in-out param. Writes the `square` to the param. Returns `true` on integer overflow. */
_Bool square2(int* number) {
unsigned long sq = square(*number);
*number = (int)sq;
return sq > INT_MAX;
}
/*
Array param must have known size (expected minimum, that is, since caller can point to whatever)
Using the array as an output param (array identifiers are pointers after all)
Note: Functions cannot return an array (what’d you do, `malloc`?)
*/
/** Backport `gets_s` (consumes rest of line; no constraint handler integration) */
char* ngets(size_t n, char str[n]) {
if(n == 0)
return NULL;
str[n--] = '\0'; // '\0' termination
int c;
for(int i = 0; i < n; ++i) {
c = getchar();
if(c < '\0') // error
return NULL;
if(c == '\n')
return str;
str[i] = (char)c;
}
// Buffer overflow
do c = getchar(); while(c != '\n' && c >= '\0');
return NULL;
}
/* There are two signatures of the main function: `int main(int, char * [])` and `int main(void)`
* int argc = non-negative count of command-line args (yet can’t be `unsigned`)
* char* argv[] = array of Strings
* [0] -> "program.exe" (note: *can* be `NULL` or empty if the environment doesn’t support it.)
* [1] -> "arg1"
* [2] -> "arg2"
* …
* [argc] -> NULL
*/
int main(int argc, char* argv[]) {
for(int i = 0; i < argc; ++i)
puts(argv[i]);
puts("Enter a number:");
char input[64];
if(ngets(64, input)) {
int number = atoi(input);
if(!square2(&number)) { // Pass by Reference
printf("The square of your number is (%i)\n", number);
return EXIT_SUCCESS; // `0` and `EXIT_SUCCESS` (which may be `0` anyhow) means no errors.
}
}
puts("Your input exceeds range.");
return EXIT_FAILURE; // Anything else means failure, though `EXIT_FAILURE` is available for consistency.
// Implicit `return 0` __for `main` function only__ in C99+, undefined return otherwise.
}