CS 214 / C: Objects and types ============================= Have you logged into an iLab machine? Have you written a C program yet? Have you compiled and executed a C program that you wrote? #include #include int // return type main (int argc, char **argv) // function name and argument list { printf("Hello, world!\n"); // function call return EXIT_SUCCESS; // return statement } objects ------- a location in memory where we can store data location (where in memory the object is located) address - every byte in memory has an address multi-byte data is referred to by its first address type how big the object is (how many bytes) what operations make sense to use e.g., integer vs floating-point arithmetic value the actual bytes stored in the object note: object value is generally only known at run-time object type is only known at compile-time -> unlike Java, there is no way to query the type of an object location - may be known at compile-time (like variables) or not known until run-time (like heap objects) we can classify objects in three groups, based on lifetime static objects - always exist global variables name static objects static local variables name static objects string literals functions stack objects - tied to a function call created when function begins, destroyed when function returns local variables heap objects - explicitly allocated and deallocated not named by any variable -> we can only refer to these indirectly (by address) -- int count (void) { static int n = 0; n++; return n; } --- C's type system --------------- primary purpose: guide the compiler during code generation secondary purpose: detect some errors types integer types can be signed (default) or unsigned can be default size, short, or long int - default size, signed unsigned long int - long size, unsigned short - short size, signed unsigned - default size, unsigned C does not define the actual sizes rules are: char < short < long short ≤ int ≤ long for modern hardware, we usually have short is 2 bytes regular is 4 bytes long is 8 bytes sizeof(int) <- gives the number of chars needed to store that type char - can be signed or unsigned everything in C is sized in multiples of chars usually one byte (8 bits) C does not mandate a character encoding usually ASCII (or some superset) 'A' == 65 character literals are automatically converted to ints by the compiler floating-point float - single-precision floating-point double - double-precision floating-point almost always IEEE floating point 4 and 8 bytes, respectively generally math will use doubles (or extended-precision) internally only use float if you are pressed for space promotion and casting C usually converts number types as needed to make the math make sense int x = 3; float y = ((float) x) / 2; int m = -1; unsigned n = 1; is m < n ? be explicit: (unsigned) m < n -- false m < (singed) n -- true literals writing a number with no decimal points defaults to signed int 345 123123123123123L - signed long int 234U - unsigned int 234123432UL - unsigned long int #include defines constant such as INT_MAX, UINT_MAX int x = INT_MAX; // largest possible signed int x++; // undefined behavior! if (x > x + 1) { // can never execute, according to C } use the undefined behavior sanitizer to detect undefined behavior at run-time -fsanitize=undefined -fsanitize=undefined,address