/home/you / cs31 / weeklylab / week01 / Makefile printtypes.c testprog.cHere are the commands to run to create the directory structure:
cd # move into your home directory mkdir cs31 # make a new directory named cs31 cd cs31 # move into your cs31 directory pwd # print current working directory mkdir weeklylab cd weeklylab mkdir week01 cd week01 pwd # should be: /home/you/cs31/weelylab/week01This cp command copies everything (*) from my week01 sudirectory into your current working directory (.):
cp ~newhall/public/cs31/week01/* .
We will use the gnu compiler, gcc, to translate C to an executable form:
gcc testprog.cThen enter the path name of executable file on the command line to run it:
./a.outgcc supports command line options to include debug infortmation in the executable file (-g) and to specify the name of the executable file (-o filename) rather than use the default a.out. For example:
gcc -g -o testprog testprog.c ./testprogWe will often use make to compile code. make executes the gcc commands listed in the Makefile to compile the two programs:
make # compiles testprog.c and printtypes.cIf you run make clean it will remove the executable files (they can always be re-compiled from .c code):
make clean # removes executable files testprog and printtypes
Here is some more information about the basics of editing, compiling and running C programs on our system
vim testprog.cNotice the following in this program:
make ./testprog
1 byte: | 2 bytes: | 4 bytes: | 4 or 8 bytes: (depends on arch) |
8 bytes: | char | short | int | long | long long |
unsigned char | unsigned short | unsigned int | unsigned long | unsigned long long |
When you allocate a variable of a specific type, you get a storage location of the appropriate number of bytes associated with that variable name:
int x; // 4 bytes of storage space to store a signed integer value unsigned char ch; // 1 byte of storage space to store an unsigned integer value
### Specifying the numberic representation: %d: print out value in decimal (base 10) %u: print out value in unsigned decimal (base 10) %x: print out value in hexidecimal (base 16) %o: print out value in octal (base 8) (there is no formatting option to display the value in binary) ### Specifying the type: %d: int (to print numeric values of int, short, and char args) %ld: long int %lld: long long int %u: unsigned %lu: long unsigned %llu: long long unsigned %p: an address value %f: float or double %lf: double %e: float or double in scientific notation %g: float in either %e or %f format %c: char (ex. 'x') %s: string (ex. "hello there") ### Specifying field width: %5d: print out the value in decimal in a field of with 5 %-5d: print out the value in decimal in a field of with 5, left justified %6.4f: print out a float in a field with of 6 with a precision of 4
// sum: a function that computes the sum of two values // x, y: two int parameters (the values to add) // returns: an int value (the sum of its 2 parameter values) int foo(int x, int y) { int z; // a local variable declaration z = x + y; // an assignment statment return z; // return the value of the expression z } // a function that does not return a value has return type void void blah( ) { printf("this function is called just for its side effects\n"); } int main() { int p; // local variable declaration p = sum(7, 12); // call to function that returns an int value printf("%d\n", p); blah(); // call to void function return 0; }
gdb's print command can be used to print the value of a expression in different representations (binary, decimal, hex); you can use it as a simple calculator to verify answers to hex, binary, and decimal arithmetic. For this use of gdb, we don't have to have an executable to run gdb on. We can just run gdb, and then call its print command:
$ gdb # print an expression in different representations: # (/t in binary, /x in hexidecimal, default is decimal): (gdb) print/t 1234 # print/t: print decimal value 1234 in binary format # p is shorthand for print (gdb) p/x 1234 # p/x: print value in hexidecimal format (gdb) p/d 1234 # p/d: print value in decimal format (the default) # 0x is the prefix for a hexidecimal literals # 0b is the prefix for a binary literals # no prefix: for decimal literals (gdb) p 0xabf1 # print the hex value abf1 as decimal (gdb) p 0b0101 # print the binary value 0101 as decimal (gdb) p/t 0x1234 # print the hex value 0x1234 as binary # (note: leading 0's are not printed out) (gdb) p/d 0b1010 # print the binary value 01010 as decimal (gdb) p/x 0b10100000 # print a binary value in hex (gdb) p/t 0b101001001 + 0xa2 # add a binary and a hex value, print result in binary # you can re-cast a value as a specific C type: (gdb) p/t (char)(12) # tell gdb that the value 12 is a char (1 byte) and print as binary (gdb) p/t (char)(-12) # print -12 char value (1 byte) in binary