CMSC 216 Midterm 1- New

Ace your homework & exams now with Quizwiz!

Input scanf() function

- scanf("formatstring", &variable1, &variable2, &variable3, ...); - The format string has the same basic structure as in printf() - To match data entered in the input, use the same kinds of formatting expressions and format specifiers in the format string as for printf() %d match a decimal integer %f match a floating point value %c match a character

Conditional compilation

#if const-expr1 code here is included by the preprocessor if const-expr1 is true #elif const-expr2 code here is included by the preprocessor if const-expr1 is false and const-expr2 is true #else code here is included by the preprocessor if const-expr1 is false and const-expr2 is false #endif

Basic string library functions

#include <string.h> size_t- unsigned integer type capable of representing the size of the largest possible object in the computer size_t strlen(const char *str); • strlen(NULL) generates a segmentation fault • Comparing strings: int strcmp(const char *s1, const char *s2); - Works just the same as s1.compareTo(s2) did in Java: • Returns negative number if s1 is less than s2 • Returns positive number if s1 is greater than s2 • Returns 0 if s1 and s2 match character for character • Copying strings: strcpy(char *dest, const char *src); - Copies the string in src to dest - It is up to the programmer to ensure that dest is an array with enough characters to hold the string • Being lazy with this function can result in buffer overflows

Numeric literals

- 30000 is of type int, but 30000L is of type long - 2.5 is of type double, but 2.5f is of type float

Storage

- Automatic: the previous variable j has automatic storage, meaning it is no longer maintained after its function returns • Default for block-scoped variables - Static: variable exists throughout the entire life of the program • Global variables have this kind of storage • Initializations to static variables occur only once • We can make block-scoped variables static

Identifier scope

- Block scope: a variable declared inside a block is visible only within the block (includes nested blocks inside that block) - File scope: an identifier declared outside of any block is visible everywhere in the file after the declaration

Bitmasking

- Clear bit: AND with 0 - Check bit: AND with 1 - Set bit: OR with 1 - Flip bit: XOR with 1

Output (printf() function)

- printf("formatstring", expression1, expression2, expression3, ...); - A function with a variable number of arguments! • Within the format string, normal characters print as themselves, and: - To print values of expressions use format specifiers, for example: %d print an integer in decimal %f print a floating point value %c print a character %s print a character string

Tools (compiler options)

-fmudflapth -lmudflap

Numeric base conversion

Computer only works in binary (base 2)

Accessing fields of a structure

Dot operator: struct pixel { int x, y; char color; }; struct pixel p1, all_pixels[2]; p1.x = 1; p1.y = 2; p1.color = 'r'; all_pixels[0].x = 4; all_pixels[0].y = 5; all_pixels[0].color = 'b'; all_pixels[0].x++;

Assigning and comparing structures

Each field is copied for an assignment Pixel a, b; ... a = b; Is a == b true now? Two issues: - a and b are still separate objects in memory - Can't just compare bits - what if there's unused space? Because it doesn't make sense to do these types of comparisons, the == won't compile

Tools (gdb)

gdb a.out • To exit (quit), q • To list the code (list), l • To run the program (run), r • To set breakpoints (break), b - You need to set at least one breakpoint otherwise your code will be run to completion • To inspect variables (print), p • To execute a statement/function call (next), n • To execute a statement/function call (steps into the function), s • To continue execution, continue, c • To see the frame stack, where • To change the stack frame, frame - Example: frame 1 • To clear breakpoint, clear - Example: clear 25 • To identify where a core dump takes place - (gdb) where • What happens when there is an infinite loop • To do input redirection - (gdb) r < public01.in • How about recursion • To delete all breakpoints, delete

scanf family

int scanf(char *fmt, ...); - reads formatted input from stdin • int fscanf(FILE *stream, char *fmt, ...); - reads formatted input from stream • int sscanf(char str[], char *fmt, ...); - reads formatted input from the string str

Working with other bases

printf() has format specifiers to allow printing of values in hex or octal (not binary, though) - %x / %X : hexadecimal (a-f/A-F) - %o : octal "%08x" often used for printing unsigned ints as zero-padded, 8- digit hex numbers - Notice that 0x is not added to the value printed

Splint

splint p1.c

Use of symbolic constants

• #define preprocessor directive #define name value • All occurrences of name in the source file are replaced by value

Other preprocessor capabilities

• #undef name - Undefine symbols in order to assign a new value to them • The compiler can define symbols at compile time: gcc -D LSIZE=100 defining_symbol.c - Defines LSIZE to 100 while compiling the file, just as if #define LSIZE 100 appeared in the program

Lvalue and Rvalues

• An rvalue is anything that can appear on the right side of an assignment statement - Virtually any expression • An lvalue is anything that can appear on the left side of an assignment statement - Values that represent a place to store a value • The right and left sides of an assignment statement are treated differently - Right hand side is a value, left hand side is a location to store a value (an address)

Bitwise operators

• Bitwise AND: & • Bitwise OR: | • Bitwise NOT (unary): ~ • Bitwise XOR: ^ • Assignment: &= |= ^=

Unions

• But all fields share the same memory space, so are only as large as largest field

C Functions

• C Functions have the following format returnType functionName(parameter list) { /* statements */ } • To call a function - functionName(argument list);

Basic arithmetic operators

• C also performs integer division (rather than floating point division) when both operands are integers - So, 3.0 / 2.0 == 1.5 (also == 3 / 2.0) - But, 3 / 2 == 1

String literals

• Character arrays vs. character pointers . The following two declarations are not equivalent: char name[] = "Mary"; // string variable char *name = "Mary"; • First declaration creates an array - What you should be using if planning to change the name value • Second declares name as a pointer to a string literal - Should be declared as const char *name = "Mary";

Variable declaration

• Declaring a variable provides space for it in memory - "int x;" will cause 4 bytes on the stack to be reserved for x • No initialization takes place! And unlike Java nothing will prevent you from using that random value • Consider this code: int x; printf(" %d\n", x); • Output for above code might be 0, -2349235, 82373, ... • It's up to you to initialize your variables properly

Function pointers

• Each function is located somewhere in memory; this means we can create a pointer to it • Declared like this: - void (*fp)(int); • fp is a pointer to a function that returns void and has a single parameter (which is an int) - int *(*fp2)(char *, int); • fp2 is a pointer to a function that returns a pointer to an int, and has 2 parameters (a pointer to char, and an int)

Boolean operators

• In C 0 is false, and any other value is considered true

Generic pointers

• Pointers to void (variables declared as void *) can point to any type • No casts needed with void * pointers • You can't dereference a void * - you first need to cast or assign it to a real pointer type - Value obtained from a dereference depends on the type of pointer

Compilation stages

• Preprocessor - Used to make sure the program parts see declarations they need (and other purposes too, e.g., macros) - Directives begin with a # (pound sign) - Do not end in a ; like C statements do • Translation - Makes sure individual parts are consistent within themselves - Creates an object (.o) file • Linking - Joins one or more compiled object files together • Includes matching function call to callee across separate files • And matching global variable use to where it's defined - Makes sure caller/callee consistent with each other - Creates an executable file (the convention in Unix is no filename extension for executable files, although sometimes .x or .exe are used). Default: a.out

Arrays of pointers

• We can also have an array of pointers: int *nums[3]; - An array of 3 pointers to int

File inclusion

• We can solve this problem using conditional compilation inside common_struct.h: #if !defined(COMMON_STRUCT_H) #define COMMON_STRUCT_H (previous contents of common_struct.h here) #endif • This solution is seen in many header files • Example: include_files_example

Garbage pointers

• When a pointer variable is declared, it points to whatever address was in the memory location allocated for the pointer variable(no initialization) • Trying to dereference this random address will generally result in one of three Bad Things: - Accessing a memory location you don't have permission to access (a "segmentation fault") - Violating the computer's alignment policies (a "bus error") - Silent failure: everything appears to work right... for now

Comma operator

• Yes, the comma is an operator • Evaluates left operand, then right operand • Value of expression with comma is value of last operand • Has lowest precedence of all operators • So what gets stored in i after each statement? What does each statement evaluate to? i = 1, 2, 3, 4; i = (1, 2, 3, 4);

The typedef keyword

• You can give types new names - Eases readability and maintainability - Creates alias for a type • typedef existing-type new-name; - The type may be created along with the typedef usage, as we'll see with structures - typedef double Dollars; Dollars x, y = 1.25; - x and y are double - typedef int MyFavoriteType;

Structure initialization

• Zeroes used to fill uninitialized fields when an initializer is used

Line-oriented I/O

• char *fgets(char *buf, int size, FILE* stream); - Reads chars from stream, storing in buf, stopping when either • A newline is read; or • size - 1 characters are read - null character ('\0') is always appended to string - Unlike gets, fgets includes the newline in buf - NULL returned on error or EOF - On success (no error and non-EOF), returns buf • int fputs(const char *str, FILE *stream ) - Returned value is non-negative on success, and EOF on failure

Tools (diff)

• diff - Allow us to see differences between files - To use just run diff with the two files • diff file1 dile2 - The option -bwi ignores whitespaces, but not empty lines • diff -bwi file1 file2

C Functions

Arguments are passed by value Can we have method overloading?- NO

Compiling a C Program

C programs must be compiled to be executed • Use the gcc program to build your programs -g enables debugging -Wall warns about common things that may be problems -o filename places executable in filename -c only compiles to object file, don't link

The -> Operator

Given a pointer to a structure we can use the -> operator to reference the fields of a structure

The const modifier

Indicates that a variable can't be changed (enforced by compiler) • Order of type specifier and const modifier DOES matter when dealing with pointers: int i = 4, j = 5; const int *p = &i; /* pointer to constant int */ int * const q = &j; /* constant pointer to int */ p = &j; /* OK */ *p += 5; /* ERROR */ q = &i; /* ERROR */ *q+=23; /*OK*/

Data sizes in C

Note that variables of type char are guaranteed to always be one byte.

Array parameters

Parameter declaration int a[] equivalent to int *a

Aside: parameters are variables

Pixel increase_y_value(Pixel p, int delta) { p.y += delta; /* will not modify original */ return p; }

Compiling a program

Source files (*.c) compiled into object files (*.o) 1. Source file is first preprocessed a. gcc -E to see output 2. Preprocessed file is then compiled to assembly a. Scanner/parser b. Type checker c. Code generator d. Optimizer 3. Assembler converts assembly code to object code • Object files are converted into an executable 1. Done by the linker, which resolves symbols a. Match function use to its definition b. Global variable declaration and external use

Structures and functions

Structure arguments are passed by value We can return structures from functions

Structure storage

To minimize unused space, order fields from longest to shortest

Bit operations

Usually unsigned integers are used for bitwise operations

More make features

clean: @echo "Removing object, executable, and core files." rm -f *.o *~ core core.* • Preceding an action line with an at sign (@) keeps make from echoing the command when make is ran • A long line in a makefile can be continued to the next line by ending it with a backslash • .PHONY - Targets in your makefile which do not generate the file with the target name should be PHONY. This typically includes clean, all, install - You just want make to execute some commands

Array initialization

int w[i]; /* both illegal: size must be */ int x[]; /*knownatcompiletime*/ int y[4] = {2 int temp[5]; temp = {1, 1, * i, 3 + 2}; /* illegal: initializer values must be known at compile time */ /* this OK */ 2, 3, 5};/*illegal:initializercanonly be used as it first comes into existence */ • Zeroes pad the array when initializer is short • Use of an initializer allows size to be omitted

Using typedef with function pointers

typedef char *(*Str_func)(char *); char *strdup(char *str) { ... } ... Str_func sf = strdup; char *copy = sf(str);

Combining typedef and struct

typedef struct pixel { int x, y; char color; } Pixel; Pixel p1;

Tools (valgrind)

valgrind a.out

About creating structures

• Example: struct { int id_number; char last_name[10]; char first_name[10]; double salary; } emp1, emp2; • Notice tag is missing • Declares two variables (emp1 and emp2) • You cannot define any other variables of this type • Omitting tag means you create a unique type for the variables listed - Even if member-lists are the same - Prevents use of those structs as function arguments

Basic dependency rules

• Executables depend on all the object files that could compose the program • Executables made by linking object files • Object files depend on their respective source files (x.o depends on x.c), and any header files #included with quotes in the source file - x.o depends on y.h if x.c has "#include "y.h"" - Notice we don't generally worry about things included via angle brackets (e.g., <stdio.h>) • Object files made by compiling *.c files with -c flag

Stream I/O Overview

• FILE * type represents an open stream • Use fopen() to open the file (read/write) - FILE * input = fopen("data.txt", "r") - FILE * output = fopen("results.txt", "w") • Read data with - fgetsreads a line - fscanfsimilar to scanf, but with a stream as parameter • Write data with - fputswrites a line - fprintf similar to printf, but with a stream parameter • Use fclose() when done

Opening/Closing files

• FILE *fopen(char *filename, char *mode); - Arguments are strings - mode specifies access mode: • "r" - read; file must already exist • "w" - write; if file exists, it is overwritten • "a" - append; if file does not exist, it's created • There are other modes ... - Returns NULL on failure; can use perror() to see why it failed • int fclose(FILE *fp); - Closes a file flushing output if necessary - Returns 0 on success - Failure does occur

scanf family

• Format strings can contain: - Whitespace, meaning any whitespace at that point will be skipped • Many (but not all) skip leading whitespace anyway - Format specifiers which cause something to be read - Any other characters, which are then required in input • scanf() does not check for type agreement between the format specifier and the associated variable • If a given format specifier doesn't match, scanf() stops processing there • scanf() returns the number of items assigned into variables - Allows you to check whether input was read correctly • scanf() returns EOF on end-of-file

Arrays in C (Static Type)

• In C - Elements are next to each other in memory - There is no length property • Syntax for creating arrays is slightly different - C: int a[5]; creates array of 5 ints • The name of an array can be seen as a pointer to the first element of the array • Given two arrays a and b, a = b does not assign corresponding elements • Can use == and !=, but they do pointer comparison

Accessing command line arguments

• Notice we could specify char *argv[] as: char **argv • If we execute "./prog -l 53 -c -d"? - Output is: Arg #0: ./prog Arg #1: -l Arg #2: 53 Arg #3: -c Arg #4: -d • argv looks just like this, including the NULL at the end

Conditional compilation

• One type of const-expr is defined(macro-name), which has the value 1 if macro-name is defined, and 0 if not • #ifndef Allow us to verify whether a symbol has been defined • The preprocessor directive #error string stops preprocessing (and compilation) at that point, and prints string

Separate compilation

• Placing code across several files allows us to update only parts of the object code for a program when changes occur • We have been just compiling everything into an executable, bypassing the object code step

Pointers

• Pointer memory address/reference • Pointer variablesVariables whose value is an address - Informally we call them pointers • Obtaining the address of an object (&) • Accessing the object at an address (*)

Incrementing pointers

• Pointers can be incremented/decremented just like integer type variables, "moving" one element at a time - How much is added to the address depends on the size of the type to which the pointer points (as declared) • Recall arrays are contiguous memory • Incrementing pointers only makes sense when the pointers are referring to an array • With two pointers in the same array, we can determine how far apart they are return (size_t) (ptr - str);

Structures declarations

• Structures - Like arrays, hold multiple items (items need not be of the same type) - Items referred to by field names, not numerical indices struct pixel { int x, y; char color; }; - struct pixel p1;

The define directive

• Substitutes lots of text for name throughout the source file

Modification times

• Targets are only built if their dependencies have been updated, using modification times • ls can display file modification times: - ls -l list files showing their modification time, size, etc. - ls -lt list files in order of mod. time (most recent first) - ls -lrt invert the sort order of a listing • How are file modification times changed? - Changing contents of a file in any way, via a text editor or any other means, adjusts the file's mod. time - UNIX "touch" command can be used to set file mod. time if you need to do it manually • Default is to use current time, but can use any date/time • Be careful with it - can cause unnecessary compilations, or prevent necessary ones, and usually it's not needed • Let's execute touch on some of the files for the previous example

Shifting operators

• The << and >> operators shift a value a given number of bits to the left or right, respectively • Zero bits replace the vacated bits • Assignment operators: <<= >>=

Strings in C

• There is no String type in C • In C, a string is defined as a sequence of characters that is followed by a byte with the value zero - Often called: "zero byte", "null byte", "NUL" - Represented as the character literal '\0'

NULL pointer

• This is a pointer that points to the address 0, where nothing is allowed to be accessed • NULL is considered false • Defined in stddef.h, which is included by many other header files • Analogue to Java's null - What happens when you try to call a method of an object which is null? - Very similar thing happens in C when trying to dereference a NULL pointer; it's usually a segfault • Just like in Java, you have to check pointers to see if they're NULL before dereferencing them: void f(int *p) { if (p != NULL) *p = 55; }

Stream I/O Overview

• Three predefined streams for every program: - stdin: standard input (redirect with <) - stdout: standard output (redirect with >) - stderr:standarderror • We can use fprintf to direct output to one of the above streams (or to any file stream) - int fprintf(FILE *stream, char *fmt, ...); • Sends formatted output to stream • Redirection - You can redirect input using < - You an redirect output using > - You can redirect both stdout and stderr (in tcsh) using >& - You can use CTRL-D to indicate EOF • CTRL-D is not the same as CTRL-C

Identifier linkage

• To better understand linkage, let's see how we can organize C code across several C file - Example: linkage_example folder - Why we want to split code across several files? • What happens if we encounter two instances of the same identifier across different files? • A function named foo() in file1.c can cause problems if there's a function named foo() in file2.c • We can resolve these types of conflicts by changing the linkage of the functions • Linkage: a property of an identifier that determines if multiple declarations of that identifier refer to the same object • Three types of linkage - None: all declarations of an identifier refer to different entities (i.e., one copy per declaration) - Internal: all declarations of an identifier inside a given file refer to the same entity, but declarations across files refer to different entities (i.e., one copy per file) - External: all declarations of an identifier refer to the same entity (i.e., one copy per program) • Default linkage is different for different types of identifiers - All functions and file scope variables default to external linkage - Variables with block scope default to no linkage • Use extern and static to modify linkage • Remember the difference between declaration and definition • Example: linkage_example folder

scanf()

• Use %s as specifier • Array must be large enough to read data • Notice we don't use & in argument when reading a string • scanf adds a null character • Be careful with adding spaces or \n in the format string

The make utility

• Using make helps automate separate compilation, using a Makefile we write • The Java compiler can tell if it has to compile other classes than the one you've told it to compile; C compilers can't • Typing out the commands to build C programs is error-prone and can get annoying, especially if using several command- line options • Note: this is a compressed description of Make; full manual is available online

Arrays vs. Pointers

• int nums[3]; - Declares an array, allocates 3 ints' worth of space, and points the name nums to the beginning of this space - nums cannot be changed to point elsewhere - By itself, nums is treated as a constant pointer that points to the beginning of the array • int *nump; - Declares a pointer, doesn't allocate anything more than space to store an address, connects the name nump to that space - nump can be changed and assigned to

printf family

• int printf(char *fmt, ...); - Sends formatted output to stdout • int fprintf(FILE *stream, char *fmt, ...); - Sends formatted output to stream • int sprintf(char *buf, char *fmt, ...); - Formats output and places in buf, adding null byte • int snprintf(char *buf, size_t limit, char *fmt, ...); - Writes at most limit - 1 characters to buf, then null byte

Stream I/O Overview

• perror - Prints a message to standard error describing the last error encountered during a library function or system call - If you provide a string it will be printed before the default error description - It relies on the external variable errno that is set when errors occur • It is not reset for successful calls - Example: perror_example.c • strerror(errno) - Generates a string for the specified errno - You need <string.h> - errno.h includes errno • Exit codes - From stdlib.hEXIT_SUCCESS, EXIT_FAILURE - From sysexits.hEX_OSERR, EX_USAGE • Remember exit is not the same as return

Standard I/O Library

• stdio.h contains prototypes and constants for I/O routines


Related study sets

Historical-Cultural and Contextual Analysis

View Set

UNIT 2 - Chapter 9: Eating Disorders and Seep-Wake Disorders

View Set

EatRightPrep Simulated RD Test 2 T

View Set

CHEM: THERMODYNAMICS-ENTROPHY- ENTHALPY STUDY MODULE

View Set