-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathC Commands
264 lines (216 loc) · 14.4 KB
/
C Commands
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
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
The language C has grown and evolved over the years.
Since its inception, many standards were formed and new functionalities were added.
C has many commands we can use, but to do so we need to tell them program to access a certain library containing those commands.
There are the preprocessor directives, and they contain groups of commands revolving around a certain theme.
We need to add them at the very start of the program, using the #include command:
#include <LIBRARY_NAME> - Where LIBRARY_NAME is the name of the library we wish to access. Examples are:
#include <stdio.h> - Contains various functions for priting text out, user inputs, loops and various other things.
#include <math.h> - Contains mathematical functions such as the square root, setting the power of a value etc.
After adding our preprocessor directives, we need to add in our actual code, the code block that makes up our program.
We do that by writing various functions, of which every C program ALWAYS needs to contain a function called int main() {}:
#include <stdio.h>
int main() {
CODE BLOCK
return 0;
}
The return command signals an end of a function, or in this case the end of our program.
We can also define certain variables globally, so that we can use them anywhere in the program using the #define command:
#include <stdio.h>
#define PI 3.14159265359
int main() { ... }
This way, every time we use the variable PI, it will be as if we wrote the whole thing out.
By defining important variables we can save ourselves a lot of time and frustration since their values will be constant,
minimizing the chance of a typo.
These are the so called "global" variables. They retain their value throughout the entire program and can be used anywhere.
They can, however, cause certain issues if we attempt to tamper with them, so it's advised to use "local" variables.
Local variables can only be used inside the function they are initialized, keeping in mind that every single variable we use
must be initialized, otherwise the program won't compile. We initialize variables in a few different ways:
int X - Creates a variable called X which is an integer, rounding down any decimal number to an integer.
float X - Creates a variable called X which is a real number.
double X - Creates a variable called X which is a real number, being more precise than a float but taking up more memory.
long int X - Creates a longer integer.
long float X - Creates a longer real number.
long double X - Creates a longer precise real number.
Also, keep in mind that, since real numbers can't accurately be represented, when comparing them we need to use small intervals.
This only needs to be done if the numbers are a result of mathematical operations, because then their errors vary.
#define EPSILON 0.001
float A=0.05, B=0.05, X;
X = A + B; // X should now be 0.1 but there are small errors...
if (X==0.1) printf("This will never print itself"); // This won't print itself because of the error
if (fabs(X – 0.1) < EPSILON) printf("This will print itself"); // But this interval is just fine
If we don't use mathematical operations, and instead just compare numbers right after they're put into the program.
So for example:
scanf("%f, %f", a, b);
if(a==b) printf("This will print!");
The 'sizeof' operator can be pretty useful when determining the size of something.
It returns how many bytes of memory does the variable or type take up, so:
sizeof(char) returns 1
sizeof(int) returns 4
sizeof(float) returns 4
sizeof(double) returns 8
Pointers can help us solve tricky problems by using indirection:
int a=5; // Integer called 'a' with the value of 5
int* pa = &a; // Pointer to an integer called 'pa' which points to the address of 'a'
*pa+=2; // We dereference the pointer, effectively using 'a' and adding 2 to it, making a=7
const char* b; // A const pointer, meaning we can't change what address it points to
char* const c; // A pointer to a const, meaning we can't change the value of the thing it points to
const char* const d; // We can't change the value it points to, or the address it points to either
int (*p)(int) = func; // Pointer to a function called 'func' with the prototype: int func(int)
int n=*p(5) // The same as typing: int n=func(5);
A function's name is also a pointer to that function.
___________________________
Functions:
Functions in C are written like so:
FUNCTION_TYPE FUNCTION_NAME (PARAMETER_1, PARAMETER_2...){
// Function code goes here
return VALUE;
}
Here's a practical example:
int multiplyByTwo(int x){ // Function called multiplyByTwo, which takes one integer as a parameter and returns an integer
x*=2; // Multiplying x by two
return x; // Returning x as a value
}
Functions whose type is "void" don't need to have a return command to exit the function, but all others do.
Functions take parameters as values, they don't affect the value of the variable itself (unless they take in a pointer).
___________________________
Structures:
Structures serve as custom user-made data types. We form structures like so:
struct Student{
int index_number;
char name[20], surname[20];
};
We can then create a variable of the type 'Student' like so:
struct Student mike, bruce, alice;
mike.index_number=12345; // Assigns the value '12345' to Mike's index_number
printf("%d", mike.index_number);
struct Student students[100]; // An array of 100 students
struct Student *p = students; // A pointer to the array of students
*(p).index_number; // Accessing an index_number from the pointer
p->index_number; // A simpler way to do the same thing!
___________________________
Files:
We can work with files by creating a pointer to a new or existing file. We do this like so:
FILE* filename; // Creates a pointer to a file called 'filename'
filename=fopen(STRING, "USAGE") // Opens an existing file called STRING or creates a new one, needs to be closed...
// If opening the folder fails, fopen will return NULL, which we can use to check if the operation was a success
// USAGE is how we'll use the file: 'r'-read, 'w'-write, 'a'-append, 'r+'-read-update, 'w+'-write-update, 'a+'-append-update
// If we're working with binary files, add the letter 'b' to the end of every USAGE type ('rb', 'wb', 'ab' ...)
If we just type in the file's name under STRING, it creates (or tries to open) a file in the same directory as our main.c file.
To change the directory, simply pass a custom directory as the STRING parameter.
When typing in directory names, you must use \\ for \, etc. Be mindful of the formatting of strings in C!
As a part of the directory name '.' means we're using the current folder, and '..' is the folder ABOVE it in the hierarchy.
fgetc(filename) // Reads a single character from filename and returns it. Returns EOF if it's the end.
fputc(CHAR, filename) // Puts CHAR in the file 'filename' Doesn't work if the usage is 'r' for read-only
fputs(STRING, filename) // Puts STRING into the file called 'filename'
fgets(STRING, LENGTH, filename) // Grabs a string LENGTH long from the file 'filename' and puts it in STRING
// Reads at most X-1 characters from the first \n, which is also stored in the string and followed by \0
// Returns a pointer to the found STRING if the operation was a success, and NULL if it failed
fscanf(filename, "FORMATS", &VARIABLES) // Reads from the file, returns the amount of read variables
fprintf(filename, "TEXT", VARIABLES) // Writes to the file, returns the amount of characters it put into the file
feof(filename) // Returns 1 if we're at the end of the file
ferror(filename) // Returns 1 if the last operation caused an error, good for checking for errors
fseek(filename, VALUE, CUSTOM) // Moves the cursor which is used to read from or write to the file
// For CUSTOM, SEEK_SET is the beginning, SEEK_END is the end, so fseek(filename, 0, SEEK_SET) returns the cursor to the start
ftell(filename) // Returns the position of the cursor, usually as the number of bytes from the start
long position;
position=ftell(filename); // Grab the current cursor position
/* We move the cursor here while doing something else */
fseek(filename, position, SEEK_SET); // Return cursor to position
// These are used for binary files
fread(POINTER, sizeof(TYPE), LENGTH, filename) // Reads LENGTH many variables of TYPE from 'filename' and puts them in POINTER
fwrite(POINTER, sizeof(TYPE), LENGTH, filename) // Same principle, returns the amount of variables successfully written as INT
___________________________
Now that we have the basics out of the way, let's get to know the different libraries which are supported in C.
________________________________________________________________________________________________________________________________
Library <stdio.h>:
printf("TEXT AND FORMAT MODIFIERS", VARIABLES) // Prints out the text, returns the amount of characters printed out
// Formats: %d(int), %u(unsigned int), %f(float, double), %g(precise), %e(scientific), %c(char), %s(C-string), %n(nothing)
// Specifiers: hh(char), h(short), l(long), ll(long long), L(long double), *(for scanf, doesn't store the input in any variable)
// Escape sequences are sets of characters which are displayed differently than the way they're typed inside a printf function:
\n - New line
\t - Tab
\\ - Backslash (a single backslash, as you can see, is used to mark the start of an escape sequence)
\b - One character to the left (erase)
\r - Move back to the start of the line
\v - Vertical Tab
\f - New page (no effect on screen)
\" - The " character
\' - The ' character
\0 - Null character, marks the end of a character array
\NUMBER - Octal constant, put in any number
\xNUMBER - Hexadecimal constant
// Since we can add different things to a printf format (like %5.2f), here's a list of subspecifiers that go after the %:
- Allign left
+ Always print a signed number
0 Fill excess reserved space with zeroes
. Set precision of the output
*.* Add the reserved space and precision as parameters at the end of printf, but before the actual variable
scanf("FORMAT MODIFIERS", VARIABLES) // Takes an input and places is in the corresponding variable, %lf for double
// Returns the amount of variables which were taken as input, test input like:
a=scanf("%d", x); // Works if the user inputs a letter, doesn't work for real numbers
if(a==0) printf("No input."); // (the decimal is treated as a new number), doesn't work for SPACE inputs
getchar() // Prompts a single char input and returns it, allows for constructions like a=getchar();
putchar(CHAR) // Prints CHAR to the screen
switch(VARIABLE){
case VALUE:
...
break;
default:
...
}
________________________________________________________________________________________________________________________________
Library <math.h>:
pow(VARIABLE, EXPONENT) // Returns VARIABLE to the power of EXPONENT
sqrt(VARIABLE) // Returns the square root of VARIABLE
fabs(VARIABLE) // Returns the absolute value of VARIABLE as a type 'double'
sin, cos, tan, asin, acos, atan // Trigonometry
log(VARIABLE) // Natural logarithm
log10(VARIABLE) // Logarithm with the base 10
floor(VARIABLE) // Rounds VARIABLE down
ceil(VARIABLE) // Rounds VARIABLE up
round(VARIABLE) // Rounds VARIABLE up or down, depending on the value (down for <0.5)
fmod(VARIABLE) // Remainder when dividing with a real number
________________________________________________________________________________________________________________________________
Library <stdlib.h>:
abs(INTEGER) // Returns the absolute value of INTEGER as an int
exit(INTEGER) // Exits the program from any function with exit code INTEGER
int rand() // Returns a random number from 0 to 2^31 - 1, needs a seed to be random
// For a random number between [a, b), use: int x = a + rand()%b;
srand(INTEGER) // Uses INTEGER as a seed for the random selection, such as 'time(NULL)'
VARIABLE=malloc(INTEGER*sizeof(TYPE)) // Used to dynamically allocate enough memory for INTEGER variables of TYPE
free(VARIABLE) // Frees the dynamically allocated memory of VARIABLE
qsort(ARRAY, SIZE, sizeof(TYPE), FUNC) // Used to apply the function FUNC(needs to take in two const void* to sort the ARRAY
________________________________________________________________________________________________________________________________
Library <time.h>:
time_t time(time_t* t) // Returns the number of seconds between now and 1.1.1970. at 00:00:00
________________________________________________________________________________________________________________________________
Library <string.h>:
strlen(C-STRING) // Returns the length of the string passed as the argument
strcmp(STRING_1, STRING_2) // Returns 0 if the strings are equal, >0 if the first is ahead and <0 otherwise
strchr(STRING, CHAR) // Returns the pointer to the first instance of CHAR in STRING
// Can be used to find all examples of one char by using a while loop with:
char* POINT_STRING = STRING;
while(POINT_STRING!='\0'){
printf ("Found at %d\n", POINT_STRING-STRING+1); // POINT_STRING-STRING+1 gives us the location
POINT_STRING=strchr(POINT_STRING+1, CHAR); // POINT_STRING+1 means we start AFTER the last find
}
strstr(SOURCE, TARGET) // Returns a pointer to where TARGET is found inside of the SOURCE
strcpy(DESTINATION, SOURCE) // Copies one C-string to the other, deleting all previously stored data in the process
strcpy(DESTINATION, SOURCE, LENGTH) // Replaces only LENGTH characters, meaning we can edit the middle of a string
strcat(STRING_1, STRING_2) // Concantenates (merges) the two strings into the first one
Warning: since 'strcat' and 'strcpy' can potentially crash your program from buffer overflow, you should use these instead:
char STRING_1[100], STRING_2[100];
STRING_1[99]='\0'
strncat(STRING_1, STRING_2, 99-strlen(STRING_1))
strncpy(STRING_1, STRING_2, 100);
strtok(STRING, "CHARACTERS"); // Cuts the string up into substrings between the passed CHARACTERS
char text[100];
char* p;
p = strtok(tekst, " .,");
while (p != NULL){
printf("Word: %s\n", p);
p = strtok(NULL, " .,"); // We pass NULL as the first argument to tell it we're still using CHARACTERS
} // strtok destroys the original string by putting \0 at CHARACTERS !!!
sprintf(STRING, "TEXT", VARIABLES) // Like a normal printf, but puts the TEXT into the STRING instead of on the screen
sscanf(STRING, "%FORMAT", &VARIABLE) // Like a normal scanf, but grabs variables from the STRING instead of prompting
________________________________________________________________________________________________________________________________