|
|
|
Lecture 9 —printf, declarations, preprocessor
|
|
|
|
|
pointer review
|
|
|
|
|
variables are labels for a location in memory where some data is stored
|
|
|
|
|
variable names are never actually stored — they disappear once a program is compiled
|
|
|
|
|
a pointer like int *ptr is just another variable
|
|
|
|
|
what’s different is that the data it labels is the memory address of other data.
|
|
|
|
|
left values vs right values (in an assignment)
|
|
|
|
|
left_expression = right_expression
|
|
|
|
|
left expressions get evaluated to locations (addresses)
|
|
|
|
|
right expressions get evaluated to values
|
|
|
|
|
values include number and pointers (addresses)
|
|
|
|
|
Rule for variables
|
|
|
|
|
in a left expression, a variable is a location
|
|
|
|
|
in a right expression, a variable is evaluated to its location’s contents
|
|
|
|
|
dangerous for a function to return a pointer to a local variable
|
|
|
|
|
int* f() { int x = 5; int *p = &x; return p; } int* g() { int x = 10; int *p = &x; return p; } int main() { int *p = f(); int *q = g(); }
|
|
|
|
|
what will the value of *p be at the end of main
|
|
|
|
|
10, it will have been overwritten since it’s pointing to memory no longer owned by f
|
|
|
|
|
exercise: what size of array do we need to store the string “funtimes”
|
|
|
|
|
9: [‘f’, ‘u’, ‘n’, ‘t’, ‘i’, ‘m’, ‘e’, ‘s’, ‘\0’]
|
|
|
|
|
exercise: write a function to compute the length of a string
|
|
|
|
|
not counting null terminator
|
|
|
|
|
int strlen(char *str) { int count = 0; for ( ; s[count] != ‘\0’; count++) { } return count; }
|
|
|
|
|
another way: int strlen(char *str) { int n; for (n = 0 ; *s != ‘\0’; s++) { n++; } return n; }
|
|
|
|
|
printf, scanf
|
|
|
|
|
printf outputs to stdout, scanf reads from stdin
|
|
|
|
|
both take a format string
|
|
|
|
|
a string with special control sequences that indicate the type of data being output or input
|
|
|
|
|
these control sequences are matched with the arguments that follow the format string
|
|
|
|
|
examples
|
|
|
|
|
http://www.cplusplus.com/reference/cstdio/printf/ printf ("Characters: %c %c \n", 'a', 65); printf ("Decimals: %d %ld\n", 1977, 3000000000L); printf ("Preceding with blanks: %10d \n", 1977); printf ("Preceding with zeros: %010d \n", 1977); printf ("floats: %4.2f %+.0e %E \n", 3.1416, 3.1416, 3.1416); printf ("Width trick: %*d \n", 5, 10); printf ("%s \n", "A string");
|
|
|
|
|
line_count example
|
|
|
|
|
declaration vs definition
|
|
|
|
|
declaration gives the compiler the basic information about how something is used
|
|
|
|
|
type
|
|
|
|
|
number of parameters
|
|
|
|
|
for example: int strlen(char *str); declares the strlen function without defining it
|
|
|
|
|
called a function prototype
|
|
|
|
|
things must be declared before they can be used
|
|
|
|
|
something can be declared any number of times (though not more than once per scope/file)
|
|
|
|
|
definition provides the actual value or behavior
|
|
|
|
|
for example: int strlen(char *str) { int count = 0; for( ; s[count] != ‘\0’; count++) { } return count; } defines the strlen function
|
|
|
|
|
preprocessor
|
|
|
|
|
separate first step of compilation
|
|
|
|
|
#include used to bring in declarations from other files
|
|
|
|
|
connecting declarations with definitions in other files takes place in a step called linking
|
|
|
|
|
#include <filename> searches for standard library files
|
|
|
|
|
#include "filename" searches in the same directory as the source file
|
|
|
|
|
#define name replacement text does simple substitution
|
|
|
|
|
everywhere in the file where the token name appears, replacement text is substituted
|
|
|
|
|
gcc -E stops compilation after preprocessing and outputs the results to stdout
|
|
|
|
|
compilation
|
|
|
|
|
gcc -Wall -std=c11 -g -o output_file input_files…
|
|
|
|
|
exercise: extend to print out character count as well
|
|
|