CEG 221 Lesson 3 Review II Beyond Mr

CEG 221 Lesson 3: Review II & Beyond Mr. David Lippa

CEG 220 & Beyond • Advanced Input/Output – Text I/O, Void pointers, Binary I/O • Advanced Data Types – – Pointers to Basic Types & Pass By Reference Enumerated Types (enum) Structures (struct) & Unions (union) Pointers to Advanced types & Pointers to Pointers • Advanced Programming – Multiple files to separate interface from implementation – Modifiers on variables (static, auto, extern) – Modifers on functions (static vs. non-static) • String Processing using <string. h>

File Input / Output • Just as you can get/give user input from the terminal with scanf/printf, you can do so to/from strings (sscanf, sprintf) and files (fscanf, fprintf). • fscanf/fprintf take an additional parameter, the input (or output) stream, as its first argument • These functions are used for text input/output and are located in stdio. h

Text Input/Output • Prototypes: – – fscanf(FILE* p. Stream, const char *p. String, …) fprintf(FILE* p. Stream, const char *p. String, …) sscanf(char *p. Source, const char*p. String, …) sprintf(char *p. Destination, const char*p. String, …) • Uses: conversions, (ie. converting “ 3. 14159” to the double 3. 14159), writing text to files for verification of data values, writing cross-platform setting files (to avoid endian issues)

Analysis of Text I/O • Advantages: easy for cross-platform data storage – let’s the processor put the bytes in the proper order with scanf/printf; easy to verify correct results; generally more compressible than their binary equivalents • Disadvantages: files can get very large (especially those, such as images)

Introduction to Binary File I/OO • Most files are stored in binary format, writing raw bytes to disk, and then later read in and interpreted • Use fread and fwrite from <stdio. h>, which are significantly faster to read in giant chunks of data • Same prototypes for both fread/fwrite: – size_t fread(void *p. Memory, size_t size, size_t num. Elements, FILE *p. Stream);

What is a void*? • We’ve all seen the return type void before – it means “nothing” (ie. A function that returns void returns nothing). So a void* is a pointer to nothing, right? WRONG! • In fact, it’s a pointer to anything. • A void* can be a pointer to an int, a char*, a char**, a FILE*. • Because of this ambiguity, we cannot dereference a void* (ie. If p. Void is a void*, (*p. Void) is ambiguous

Using fread & fwrite • Arguments: – p. Memory: the address to read/write from/to – size: the size of each element (sizeof) – p. Stream: the stream read/written from/to – Returns the number of elements read/written • Remember: – Allocate new memory when using fread – either dynamically (with malloc) or statically (passing in the address using &). (ie. integer; struct p. Type p; see next slide for details)

Examples: • To read an integer: – integer; – fread(&integer, sizeof(int), 1, p. Input. File) • To read a structure that was written to disk – struct Person. Type p; – fread(&p, sizeof(struct Person. Type), 1, p. Input. File) • In class: using fseek to jump around

Introduction to Advanced Types: Terms • Pointer – a memory address that is also a variable • We must first define a variable before we can declare and use it • Definition of a variable – specifies its structure and members • Declaration of a variable – creates an instance of a variable of a type, according to its types definition

Advanced Data Types: Pointers to Basic Types • We can create a pointer (a memory address) to a variable. • Pointers should be initialized to NULL, the empty memory address (also 0 x 0000) • Pointers are always an ADDRESS, never a value • Dereferenced (convert ptr to value) with * • Use & to convert a variable to a memory address

Example: Pointers to Basic Types int i. Value = 10; int *p. Int = 5; // points to the ADDRESS 5 p. Int = malloc(sizeof(int)); // allocate *p. Int = 5; // p. Int points to memory containing 5 p. Int = &i. Value; // p. Int points to i. Value == 10 free(p. Int); // free up the memory p. Int = NULL; // reset to NULL

Example: Pointers to Basic Types (Continued) • Something wrong in the previous slide! – Cannot free up i. Value since it wasn’t malloc’d! – The memory malloc’d and formerly assigned to p. Int is LOST since we have no copy of that pointer MEMORY LEAK! • How to fix – Switch “p. Int = &i. Value; ” and “free(p. Int); ”

Implications of Pointers: Passing By Reference • Because a pointer is simply a memory location, passing pointers to functions lets us change the value passed in – a feature not previously allowed to us! • This is called pass by reference (or pass by pointer), as opposed to pass by value, where a copy is made and the copy is modified • We can use the & operator to get the address of any variable (see example in next slide)

Passing By Reference • Let’s say we have an integer and want to modify it and the function void do. Something(int *p. Int) takes an int*. We can use the & operator to get the address of an int, passing the address of that int to a function that takes an address of an int p; // create p do. Something(&p); // do sthg to p and change it

Advanced Data Types: Enums • Enumerated Types are just a glorified integer, assigned with a name and number value. They can be in hexadecimal format or in base 10 (ie. Eye. Color. Type) • They are custom data types that can be used in switch() statements or if/else chains to handle a variety of cases • Since they are ints, they can be easily written/read to/from files

Example: Enums // define Eye. Color. Type enum Eye. Color. Type { BLUE=0, BROWN=1, GREEN=2, HAZEL = 4 }; // … // declare an Eye. Color. Type called e. Color Eye. Color. Type e. Color = HAZEL; // remember HAZEL == 4 // … switch(e. Color) { BLUE: …; break; // BLUE == 0 BROWN: …; break; // BROWN == 1 … default: …; break; // this will be hit if e. Color == 3 }

Advanced Data Types: Structs • Structs are a heterogeneous data type that is a collection of all its members – Example: – struct Student. Type • • First Name, Last Name Age Social Security Number of credits taken to date – What types would all of these members be?

Defining a Structure enum Gender. Type { MALE, FEMALE }; typedef struct Person. Type { char m. First. Name[40]; // a string char m. Last. Name[40]; // a string enum Gender. Type m. Gender; int m. Age; float m. GPA; struct Person. Type *mp. Spouse; } Person;

Declaring a Structure • How to declare a struct as a variable and as a pointer: – struct Person. Type andrew; – struct Person. Type* p. Person; • We can use “typedef” to create custom types that help eliminate confusion after the struct definition – typedef Person* Person. Ptr; • Now we have Person. Ptr and Person types

Declaring a Structure (Contd) • We can now declare a pointer to a person – Person. Ptr p. Person 1, p. Person 2; instead of having to do: – struct Person. Type *p. Person 1, *p. Person 2; • Furthermore, the extension Ptr to every pointer type clarifies what is a pointer and what isn’t. If we wanted an array of Person, we could create a pointer to a Person. Ptr.
![Example: Structures • An array of 14 persons: Person my. Class[14]; • A pointer Example: Structures • An array of 14 persons: Person my. Class[14]; • A pointer](http://slidetodoc.com/presentation_image_h2/dd3242c816b30437f82dd1d0e09fed9d/image-22.jpg)
Example: Structures • An array of 14 persons: Person my. Class[14]; • A pointer to a person: Person. Ptr p. Person; • An array of 4 person pointers: Person. Ptr my. Family[4]; • What we cannot do: – Inherit characteristics (ie. An engineer is a person)

Using Structures • To access a member of a pointer, we must dereference the pointer (with *) and then the structure (with. ) • Examples: – my. Class[0]. m. GPA = 4. 00 f; – p. Person = malloc(sizeof(Person)); – (*p. Person). m. GPA = 3. 89 f; – p. Person->m. GPA = 3. 89 f; // equivalent to above – p. Person->mp. Spouse = &my. Class[0];

Advanced Data Types: Unions • A union is just like a structure in terms of memory usage and behavior, with one exception: it only contains one of its internal variables at a time. • If struct Person. Type were a union, setting the gender field would be its only contents. • Then, if the age were changed, the gender would be lost
![Side By Side: Unions and Structs struct Student. Type { char m. First. Name[30]; Side By Side: Unions and Structs struct Student. Type { char m. First. Name[30];](http://slidetodoc.com/presentation_image_h2/dd3242c816b30437f82dd1d0e09fed9d/image-25.jpg)
Side By Side: Unions and Structs struct Student. Type { char m. First. Name[30]; char m. Last. Name[40]; char m. SSN[9]; unsigned int m. Age; int m. Num. Credits. Taken; char m. Student. Status; }; union Number. Type { char m. Char; short m. Shrt; int m. Int; long m. Long; }; • Structs contain all the members in their definition • Unions only have one of their members contain information at a time – For a given union, if m. Int = 40 and m. Char is then set to be ‘A’, then the information in m. Int is gone

Pointers to Pointers • We have briefly covered pointers to pointers. Wouldn’t you rather see “Person. Ptr *p. List” instead of “struct Person. Type **p. List”? • Remember, when dereferencing p. List to make sure that enough memory was allocated and that when you dereference it, *p. List is still a POINTER

Advanced Programming: Information Hiding at a High Level • Use multiple files to separate interface from implementation – Interface: how to use the functionality provided – Implementation: how the work gets done • We can then create a library consisting of the header file (interface) and the library (implementation). No one need know how the library functions, just that it does what was intended. • Go over examples in class

Advanced Programming: Modifiers • Modifiers on variables – const – variable cannot change – static – only one copy exists within that file – extern – defined externally in some file that #includes where the extern is defined • Modifers on functions (static vs. non-static) – Static – only one copy of the function can exist • No other function may have that name and argument list

The Basics of Modifiers I: CONST • There is one time where a const variable is not quite constant – that is when it is a pointer: – 1) const char *p. Char = “Hello”; // contents can’t Δ – 2) char * const p. Ptr = …; // address can’t Δ – 3) const char * const p. Ptr 2 = …; // neither can Δ
![The 3 Cases of the const Modifier • Case (1) – p. Char[0] = The 3 Cases of the const Modifier • Case (1) – p. Char[0] =](http://slidetodoc.com/presentation_image_h2/dd3242c816b30437f82dd1d0e09fed9d/image-30.jpg)
The 3 Cases of the const Modifier • Case (1) – p. Char[0] = ‘C’; // illegal – contents can’t change – p. Char = “World”; // legal – points to something else • Case (2) – FILE* const p. File = fopen(“Data. dat”, “rb”); // legal – p. File = NULL; // illegal – pointer can’t change – fprintf(p. File, “Hello”); // legal – contents can change • Case (3) – const FILE* const p. File = fopen(“Data. dat”, “rb”); // legal – fclose(p. File); // illegal – fprintf(p. File, “Hello”); // illegal

The Basics of Modifiers II • Since extern is rarely used, just don’t worry about it • The main use of “static variables” is to ensure that only one copy of a function or variable exists – frequently fixes the “function already defined” compiler/linker error. Statics are frequently used in C++ and significantly less in C.

Next Time • Algorithm Development I – What is an algorithm? – Why are algorithms important? – Examples of Algorithms – Introduction to Algorithm Development – Example of Flushing Out an Algorithm • Questions

QUESTIONS
- Slides: 33