
87baba3cd3d1a082786516c5326c6f1f.ppt
- Количество слайдов: 50
CS 360 Program Development 2 dev 2
Agenda l Pointer basics l Pointer example l Compiling l Hints Slide 2 CS 360, WSU Vancouver
Pointer Basics Slide 3 CS 360, WSU Vancouver
Pointers vs. Arrays l Arrays are great when: 4 the data items can be conveniently numbered without many gaps 4 the maximum number of elements can be accurately estimated 4 reorganizations of the order (e. g. : insert, delete, switch) are not frequent 4 l Pointers are needed when things are more complicated 4 Slide 4 examples: – strings, command line arguments, 2 D images, file content examples: – dictionaries, queues, diagrams, family trees CS 360, WSU Vancouver
Example: Genealogy l Let's design a data structure to record House of Windsor genealogy 4 given a person, report their name, mother, and father 4 and thus grandmother, etc. l Need pointers, because: 4 no obvious numbering scheme 4 no max number of elements 4 insertions (births) common Slide 5 CS 360, WSU Vancouver
Diagram of Our Data Structure Data structure for a person: Data values: "Phillip, Duke of Edinburgh" name pointer to father pointer to mother "Queen Elizabeth III" "Charles, Prince of Wales" "Lady Diana Spencer" "Prince William of Wales" "Prince Henry of Wales" Slide 6 CS 360, WSU Vancouver
Declare Structures With Typedef l Declaration of "Person" structure: typedef struct _person { char *name; struct _person *father; struct _person *mother; } Person; l • • • "typedef" creates a new type name "Person" is this name "struct" lays out a structure the fields are "name", "father", "mother" "_person" is to allow self reference Usage: Person *charles, *diana, *william; charles diana william =. . . pointer to some storage. . . ; =. . . pointer to different storage. . . ; =. . . yet another pointer. . . ; charles->name diana->name william->father william->mother Slide 7 = "Charles, Prince of Wales"; = "Lady Diana Spencer"; = "Prince William of Wales"; = charles; = diana; CS 360, WSU Vancouver
Follow the Pointers to Navigate Around l Function to return fraternal grandmother: Person * grandma (Person *p) { Person *q; q = p->father; return q->mother; } l pointer to mother More compactly and clearly: Person * grandma (Person *p) { return p->father->mother; } Slide 8 pointer to father p CS 360, WSU Vancouver
Allocate Storage With Malloc l We get storage from the "heap" via the "malloc" routine 4 the heap is a storage pool that you manage 4 things allocated stay around until you explicitly free the space 4 initial bits in the allocated storage are unpredictable l Attempt #1: #include
Create Instances with Your Own Routine l Naturally, a routine would make the code clearer and less error prone: Person* person. New(char *the. Name, Person *the. Father, Person *the. Mother) { Person *p; p = (Person*) malloc(sizeof(Person)); p->name = the. Name; p->father = the. Father; p->mother = the. Mother; return p; } l Usage: william = person. New("Prince William of Wales", charles, diana); l Discussion: 4 how would you represent that there is no parent (e. g. : Adam and Eve)? 4 can you improve this routine? Slide 10 CS 360, WSU Vancouver
Let's Enhance the Person Data Structure … l Add field "spouse" to Person type 4 points to current spouse or is NULL if unmarried spouse "Charles, Prince of Wales" l "Lady Diana Spencer" Then, implement these routines appropriately: Person *person. New void person. Marry (Person *the. Husband, Person *the. Wife); void Slide 11 (char *the. Name, Person *the. Father, Person *the. Mother); person. Divorce (Person *the. Husband, Person *the. Wife); CS 360, WSU Vancouver
Example Usage … l Code fragment that does the following: 4 creates Charles and Diana (with no parents) 4 marries Charles and Diana 4 creates William and then Henry as their children 4 divorces Charles and Diana Person *charles, *diana, *william, *henry; charles = Slide 12 CS 360, WSU Vancouver
First steps are simple l The data type: l The creation routine: Slide 13 typedef struct _person { char *name; struct _person *father; struct _person *mother; struct _person *spouse; } Person; Person * person. New (char *the. Name, Person *the. Father, Person *the. Mother) { Person *p; p = (Person *) malloc (sizeof (Person)); p->name = the. Name; p->father = the. Father; p->mother = the. Mother; p->spouse = NULL; return p; } CS 360, WSU Vancouver
Remember, Pointers Are Just Numbers l l Pointer value = address = location = unique id of a memory chunk We diagram pointers with arrows for addresses, and boxes for chunks Person *charles, *diana, *william; charles = person. New ("Charles, Prince of Wales", NULL); charles: 1004 7001 name 1008 1012 0 0 1016 0 father mother spouse typedef struct _person { char *name; struct _person *father; struct _person *mother; struct _person *spouse; } Person; 7001 Charles, Prince of Wales (we have assumed a pointer is 4 bytes long) Slide 14 CS 360, WSU Vancouver
Pointers Are Just Numbers Person *charles, *diana, *william; charles = person. New ("Charles, Prince of Wales", NULL); diana = person. New ("Lady Diana Spencer", NULL); charles: 1004 7001 name diana: 1008 1012 0 0 0 father mother spouse 7001 Charles, Prince of Wales Slide 15 1016 2008 7021 name 2012 2016 0 2020 0 0 father mother spouse 7021 Lady Diana Spencer CS 360, WSU Vancouver
Pointers Are Just Numbers Person *charles, *diana, *william; charles = person. New ("Charles, Prince of Wales", NULL); diana = person. New ("Lady Diana Spencer", NULL); person. Marry (charles, diana); charles: 1004 7001 name diana: 1008 1012 0 0 2008 father mother spouse 7001 Charles, Prince of Wales Slide 16 1016 2008 7021 name 2012 2016 0 0 2020 1004 father mother spouse 7021 Lady Diana Spencer CS 360, WSU Vancouver
Pointers Are Just Numbers Person *charles, *diana, *william; charles = person. New ("Charles, Prince of Wales", NULL); diana = person. New ("Lady Diana Spencer", NULL); person. Marry (charles, diana); william = person. New ("Prince William of Wales", charles, diana); 1004 charles: 1004 7001 name 2008 diana: 1008 1012 0 0 2008 1016 2008 name 0 2020 0 1004 father mother spouse 7021 7001 Lady Diana Spencer Charles, Prince of Wales Prince William of Wales 2016 7021 father mother spouse 7030 2012 william: 3004 3008 3012 7030 1004 name Slide 17 2008 3016 0 father mother spouse CS 360, WSU Vancouver
Don't Know Specific Numerical Values charles: diana: 0 name 0 0 father mother spouse name 0 father mother spouse Lady Diana Spencer Charles, Prince of Wales william: Prince William of Wales 0 name Slide 18 father mother spouse CS 360, WSU Vancouver
Often Indicate Fields by Labeling the Arrows charles: diana: spouse father, mother name Charles, Prince of Wales father, mother Lady Diana Spencer william: father name Prince William of Wales Slide 19 mother spouse CS 360, WSU Vancouver
Now Let's Do Marry and Divorce … l These are the routines: void (Person *the. Husband, Person *the. Wife); void Slide 20 person. Marry person. Divorce (Person *the. Husband, Person *the. Wife); CS 360, WSU Vancouver
Fundamental Principle of Pointer Programming Diagram Your Pointer Logic Think of a specific example of the situation and action at hand Diagram how things are organized before the action (the "before picture") Modify to show effects of the action (the "after picture") Generalize to capture the general case Code the general case into C Slide 21 CS 360, WSU Vancouver
Example: person. Marry specific example: charles =. . . ; diana =. . . ; person. Marry(charles, diana); markup the change! before & after: diana: charles: name father mother spouse specific code: charles->spouse = diana; diana ->spouse = charles; general code: void person. Marry (Person *p, Person *q) { } Slide 22 CS 360, WSU Vancouver
Example: person. Divorce specific example: person. Marry (charles, diana); person. Divorce (charles, diana); markup the change! before & after: diana: charles: name father mother spouse specific code: charles->spouse = NULL; diana ->spouse = NULL; general code: void person. Divorce (Person *p, Person *q) { } Slide 23 CS 360, WSU Vancouver
Discussion l Future storage topics: 4 How memory is organized in Unix 4 How to handle running out of storage 4 How to free storage l Common errors: 4 Pointer is null 4 Uninitialized fields, so pointer is not null, but points to wrong thing 4 Forgetting the asterisk in "Person* p" Slide 24 CS 360, WSU Vancouver
Compiling and Linking Programs l l External references l Slide 25 Multiple-file programs Automating compiles CS 360, WSU Vancouver
Canonical. c File /*********** introductory comments ***********/ Identifies this file and briefly explains what it does #include
Canonical. h File /*********** introductory comments ***********/ #define MAXSIZE 100 Defines a textual substitution extern int length (char t[]); extern int sum (int x, int y); Imports external names Note: parameter names used here are independent from those used in definition, but consistency helps clarity Slide 27 CS 360, WSU Vancouver
Compiling, Linking & Executing Steps l Edit: create source files with editor: % vi x. c % vi y. c % vi z. c l Compile: translate each source into an object file: % cc -c x. c % cc -c y. c % cc -c z. c l Link: combine the object files into an executable file: % cc -o foo x. o y. o z. o l "cc" is the C compiler. Note the "-c" switch; this creates "x. o" etc. Creates "foo". Does a "chmod +x". Execute: use the new program: % foo -n "abc" < my-data > the-results Slide 28 Shell makes command line and stdin/stdout available to program CS 360, WSU Vancouver
What the Steps Do l l Editing 4 you create files that specify program logic and data using "C" 4 these are called "source" files and have extensions such as ". c" and ". h" Compiling 4 "cc" translates that specification to a form suitable for efficient machine interpretation 4 this step has sub steps we will consider later (pre-processing & assembly) 4 the files created are called "object files" (". o" extensions) Linking 4 a program is usually specified in pieces, each in a separate source file 4 also, you may reference system routines (e. g. "printf") not in your source 4 these are in "system library" files (with ". a" extensions) 4 the linker combines your objects & those needed routines 4 the files created are called "programs" (no extensions, executable attribute) Executing 4 you invoke the program, providing command line arguments and stdin/stdout 4 invocation can be done from shell or another program (more on this later) 4 doing this step with intention of testing is called "debugging" Slide 29 CS 360, WSU Vancouver
A Specific Simple Example l Edit source files with editor: x. c main() { printf ("beginn"); first (); printf ("donen"); } l y. c first() { printf ("1n"); second (); } z. c second() { printf ("2n"); } Compile each source into an object file: % cc -c x. c % cc -c z. c l Link the object files into an executable file: % cc -o foo x. o y. o z. o l Execute the new program: % foo begin 1 2 done Slide 30 CS 360, WSU Vancouver
Another Example with an External Variable l Create source files with editor: int flag = 1; /* define external variable */ main() { printf ("sum = %dn", sum (2, 3)); printf ("flag = %dn", flag); } t 1. c extern int flag; /* import external variable */ int sum(int a, int b) { int w; /* local variable */ flag = flag * 2; w = a+b; return w; } l Compile and link in one step: % cc -o bar t 1. c t 2. c l t 2. c No "-c" Use the new program: % bar sum = 3 flag = 2 Slide 31 CS 360, WSU Vancouver
External Definition & Reference Details l file 1. c Defining external names: int foo = 1; /* define external variable */ int routine 1(int a) {. . . } /* define external function */ ensure exactly one definition for each external name 4 always initialize external variables Import external names: 4 l file 2. c extern int foo; extern int routine 1(int); /* import external variable */ /* import external function */ routine 2() {. . . routine 1 (3). . . } /* define external function */ 4 l ensure definition & import agree on type (linker doesn't!) Internal names: 4 variable definitions nested in a function create internal names 4 to make a name not so nested an internal name, use "static" Slide 32 CS 360, WSU Vancouver
Include Files l Include files help ensure uses are consistent with definitions: int foo = 1; /* define external variable */ int routine 2(int a) { /* define external function */ } . . . extern int foo; extern int routine 2(int); #include "file 2. h" routine 1() {. . . routine 2(3) } file 2. h /* include correct extern's */ file 1. c . . . % cc -o bar file 1. c file 2. c l compile and link Include statement syntax: #include "file 2. h" #include
Key Files During Compiling and Linking l l l Source files: 4 C language 4 in text format x. c Libraries: 4 collections of object files 4 in binary format z. c compile x. o Object files: 4 machine instructions 4 data initialization 4 external names 4 in binary format y. c y. o z. o /usr/libm. a /usr/lib/lm. o link l Slide 34 Executable files: 4 instructions, data 4 entry point ("main") & other details foo CS 360, WSU Vancouver
Some System Include Files to Know l "Standard I/O" library: What's a "macro"? #include
Library String Routines Are Useful l The standard library has many string routines #include
Library Char Routines Are Useful The standard library also has useful character routines l #include
Compiler Operation Details. c file l l preprocessor compiler . s file assembler Compilation steps: 4 preprocessing replace #define, #include etc. 4 compilation produce assembly language from C text 4 assembly produce object files from assembly text Useful "cc" switches: % cc -c file 1. c 4 -c compile into. o file 4 -DFOO=this equivalent to "#define FOO this" in source 4 -E send preprocessor output to stdout and stop 4 -S save. s files instead of deleting Advanced switches that we will discuss later in course: 4 -g create expanded symbol table for debugging 4 -p link with profiling facility "prof" 4 -O optimize code Note: 4 switch details vary between Unix versions Slide 39 CS 360, WSU Vancouver . o file
Linker Operation Summary l How the linker finds names: % cc -o bar file 1. o file 2. o -lm 4 just link, no compile this command invokes "ld", the linker (aka "loader") in a specific way the specified files are processed left-to-right 4 external references are collected, then resolved as definitions are found 4 -l switch causes search of a system library (e. g. : /usr/libm. a) 4 the system call, stdio & run-time initialization libraries are automatically searched Notes: 4 without the "-o" switch, the file "a. out" is created 4 l l Things to remember: 4 the linker doesn't verify type consistency! 4 there is only one name space! 4 external function named "main" is the entry point 4 external names are independent from file names 4 source files can contain more than one external function Slide 40 CS 360, WSU Vancouver
Automating Compiles & Links l l Problem: 4 avoid needless compiles and links 4 remember to compile when source files change 4 remember to compile when include files change 4 remember to link when object files change Solution = "Make": 4 record dependencies between executables, objects, and sources 4 check last-modified times on all files 4 perform compiles & links only when changes occur x. c y. c z. c compile x. o y. o z. o /usr/libm. a /usr/lib/lm. o link foo Slide 41 CS 360, WSU Vancouver
We Want to Rebuild Only When Files Change l Assume we have 3 source files 4 util. h - defines interfaces to various utility routines 4 util. c - implements those routines - does #include of "util. h" 4 main. c - main routine to program - uses some util routines - does #include of "util. h" l We want to build file "foobar" 4 link together up-to-date versions of main. o and util. o foobar main. o l Let's graph dependencies: 4 arrow from A to B indicates that if B changes, then A is out-of-date (and thus B should be rebuilt) Slide 42 util. o main. c util. h CS 360, WSU Vancouver
Make Does the Job l Specify dependencies & commands in a "makefile": # a very simple makefile foobar : main. o util. o cc -o foobar main. o util. o main. o : main. c util. h cc -c main. c util. o : util. c util. h cc -c util. o main. c l util. h Edit source files as needed l util. c Build "foobar" using specifications in "makefile": % mk cc -c main. c cc -o foobar main. o util. o Slide 43 Evidently, util. o was up-to-date, but main. o was not. What could have caused main. o to be not up-to-date? CS 360, WSU Vancouver
Make Operation Details l Terminology and format: 4 "up-to-date" - doesn't need to be rebuilt 4 "target" - a file to be created 4 "prerequisite" - a file whose changes should trigger a target rebuild 4 "dependency" - a relationship between a target and its prerequisites 4 "recipe" - a sequence of commands that recreate a target 4 "rule" - a target, its dependencies, and an associated recipe target tab! l foobar : main. o util. o prerequisites cc -o foobar main. o util. o recipe main. o : main. c util. h cc -c main. c Always util. o : util. c util. h this name cc -c util. c makefile How Make ensures a target is up-to-date: 4 4 Slide 44 a file is up-to-date if it has no rule, or it exists & is newer than all of it's prerequisites otherwise, it is not up-to-date, so: – ensure all prerequisites of the target are up-to-date, recursively – perform the recipe in the target's rule CS 360, WSU Vancouver
Make Operation Details l Recipes: 4 can have any number of commands in a recipe 4 make process stops when a command fails 4 always precede the commands with tab! l Targets: % mk foo. o 4 can specify an explicit target on Make command line 4 a rule may have multiple targets 4 a target with no prerequisites is useful to automate a task What's an example? l Useful switches: 4 -n don't actually do recipes, just echo them 4 -u behave as if all prerequisites of target are not up-to-date l Make is really a tiny programming language with many capabilities: 4 default rules 4 macros 4 conditionals Slide 45 CS 360, WSU Vancouver
Common Make Errors l Circular dependencies 4 don't make a file depend on itself! l Insufficient prerequisites 4 don't forget the ". h" include files! l Missing recipe, which triggers a built-in recipe 4 there is a built-in recipe for. c to. o generation; can use this when more expert l Forgetting differences between make and shell $-substitutions 4 unfortunate inconsistency; we will talk about this later in course l No tab before a command in a recipe 4 makes command into a "target : dependencies" with much confusion A professional always automates his build process using make! Slide 46 CS 360, WSU Vancouver
Hints l Slide 47 Some practical advice CS 360, WSU Vancouver
Name Variables and Routines Carefully l Use a naming convention for variables 4 i, j, k, . . . integers 4 c, d, . . . characters there are many schemes! 4 s, t, . . . strings 4 a, b, . . arrays l Consider longer and more descriptive names 4 cur. Text 4 max. Count l what are some good guidelines? Document your declarations int max. Count; Node *e; Node *f; l /* largest count seen so far */ /* node currently considering */ /* previous value of e */ Prefix routine names with type indicator 4 dictionary. New 4 dictionary. Update Slide 48 CS 360, WSU Vancouver
Comment Concisely and Clearly l Precede "paragraphs" with a explanatory comment /******************************** string. Length (s) : number of chars before first ' ' in s ********************************/ int string. Length(char s[]) { int i; /* index of character to be examined next */ /* set i=0, 1, . . . until s[i] is ' ' */ i = 0; while (s[i] != ' ') { ++i; } /* s[0. . i-1] are not ' ', so i is length */ return i; } Slide 49 CS 360, WSU Vancouver
Exploit ANSI Declarations l It is sometimes clearer to initialize variables when they are declared: old pre-ANSI style new ANSI style int string. Length(char s[]) { int i; int string. Length(char s[]) { int i = 0; while (s[i] != ' ') { ++i; } return i; } } l A temporary variable used only within a loop can be declared within the loop: int string. Index(char *s, char c) { int i = 0; while (1) { char d = s[i]; if (d == c) return i; if (d == ' ') return -1; ++i; } } Slide 50 This code returns position of char c within string s, counting from 0. Returns -1 if c does not occur in s. CS 360, WSU Vancouver
Use Printf For Debugging l Use "printf" to display debugging information printf("XYZ = %dn", xyz); printf("x->person->name = '%s'n", x->person->name); printf("x->person->name = '%o'n", x->person->name); printf("a[%d] is %sn", i, a[i]); l Turn off or remove debugging before submitting solution #define DEBUG 1 void my. Stuff (. . . ) {. . . if (DEBUG) printf ("XYZ = %dn", xyz); . . . } l Debug by thinking! 4 4 Slide 51 CS 360, WSU Vancouver