11.07.2014 Views

C programming notes - School of Physics

C programming notes - School of Physics

C programming notes - School of Physics

SHOW MORE
SHOW LESS

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

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!