C programming notes - School of Physics
C programming notes - School of Physics
C programming notes - School of Physics
You also want an ePaper? Increase the reach of your titles
YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.
C <strong>programming</strong> <strong>notes</strong><br />
file:///F:/my_docs/web_phys2020/C<strong>programming</strong><strong>notes</strong>.html<br />
35 <strong>of</strong> 40 19/03/2007 10:06 AM<br />
/* defines the symbol DEBUG */<br />
#ifdef DEBUG<br />
/* code here is compiled if DEBUG is defined */<br />
#elif defined UNIX<br />
/* code here is compiled if DEBUG is not defined, and UNIX is defined */<br />
#else<br />
/* code here is compiled if neither DEBUG or UNIX are defined */<br />
#endif<br />
#if 0<br />
/* code here is never compiled */<br />
#endif<br />
Command-line arguments, and returning a status to the shell<br />
Up until now, our "main" function has always been declared as "int main(void)". We have seen that the integer return<br />
value is available to the UNIX "shell" in the "$?" environment variable, and this can be used to alter the execution <strong>of</strong><br />
scripts. It turns out that "main" can actually take arguments, and these are traditionally given as "int argc, char *argv[]",<br />
where argc is one plus the number <strong>of</strong> command-line arguments provided to the program, and argv is an array <strong>of</strong><br />
character strings containing the arguments. argv[0] is usually the name <strong>of</strong> the program itself. An example<br />
(statusexample.c) will hopefully clarify this:<br />
#include <br />
int main(int argc, char *argv[]) {<br />
printf("this program is called '%s'\n", argv[0]);<br />
if (argc == 1) {<br />
printf("it was called without any arguments\n");<br />
} else {<br />
int i;<br />
printf("it was called with %d arguments\n", argc - 1);<br />
for (i = 1; i < argc; i++) {<br />
printf("argument number %d was \n", i, argv[i]);<br />
}<br />
}<br />
exit(argc);<br />
}<br />
echo $?<br />
Allocating memory at run-time - malloc<br />
The situation <strong>of</strong>ten arises that you don't know the size <strong>of</strong> a data structure in your program at compile-time. For<br />
example, suppose you are writing a program to read an 2D image from a file into the computer's memory. If the size <strong>of</strong><br />
the image can vary at run-time, it would be nice not to have to pre-define the size <strong>of</strong> the memory array in your program.<br />
C allows you to do this through the concept <strong>of</strong> allocating and deallocating memory.<br />
Allocating memory means requesting the computer to give you access to a contiguous block <strong>of</strong> memory. E.g., suppose<br />
you need a megabyte; you ask the computer "can I use a megabyte <strong>of</strong> memory, and if so, can you please tell me where<br />
the memory is?". You ask the question by calling the function "malloc", which takes a single argument: the number <strong>of</strong><br />
bytes <strong>of</strong> memory that you want. malloc will attempt to allocate the memory, and if it is successful it will return a<br />
pointer to the first byte <strong>of</strong> the memory block (if malloc was unsuccessful, it returns NULL; this is a rare enough<br />
occurence for reasonable memory requests that you should handle it with "assert").<br />
Deallocating memory means telling the computer "I have now finished using this block <strong>of</strong> memory that you previously<br />
allocated for me with malloc, so you can now have the memory back again for some other purpose". You deallocate<br />
memory by calling the "free" function.<br />
Some important points to remember when using malloc:<br />
malloc returns a pointer to void, i.e., "(void *)", which just means that malloc itself knows nothing about what<br />
the block <strong>of</strong> memory is to be used for, which is fair enough since you didn't tell it. However, you do have to let<br />
the C compiler know, and you do this by type-casting malloc's result (see the example below).<br />
You should always call "free" to deallocate any memory that you have finished with. Note carefully that the<br />
argument to "free" must be a pointer obtained from malloc, and that you can only call free once for a given block