1 / 31

159.331 Programming Languages & Algorithms

159.331 Programming Languages & Algorithms. Lecture 06 - Imperative Programming Languages - Part 2 - More on Data. Records & Pointers. How do we gather together a fixed number of data items of differing type ? We use a data record or struct in C

cicero
Download Presentation

159.331 Programming Languages & Algorithms

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 159.331 Programming Languages & Algorithms Lecture 06 - Imperative Programming Languages - Part 2 - More on Data Prog Lang & Alg

  2. Records & Pointers • How do we gather together a fixed number of data items of differing type? • We use a data record or struct in C • We often need pointers to make these records self-referential or neighbour-referential • The items in a record are known as fields or components • Accessed by giving their names - known in this context as selectors Prog Lang & Alg

  3. Prog Lang & Alg

  4. In C: car_type mycar; myCar.brand = JAGUAR; We assume JAGUAR and HUMV are declared as some constants for example In Ada: My_Car : Car_Type; My_Car.Brand = HUMV; Records Example Prog Lang & Alg

  5. In C: Might be tempted to try: typedef struct{ bin_tree_type left, right; item_type value; }bin_tree_type; These do not work - we want a record to contain an item of its own type - we need to use a pointer to make this work. In Ada: (also wrong) type Bin_Tree_Type is record Left, Right: Bin_Tree_Type; Value: Item_Type; end record; We need to store the nodes left and right elsewhere as independent nodes, and store pointers to them inside our record structure. Recursive Records Prog Lang & Alg

  6. So What is a pointer? A pointer is a machine memory address (of a variable) • They “point to” a data item in the memory • Given a pointer pntr we dereference it to get the data item pointed to • In C: *pntr dereferences and gives the pointed-to data. (*pntr).field gives one field, or shorthand form is pntr->field • In Ada: Pntr.all is used Pntr.all.Field, or Pntr.Field gives one field component Prog Lang & Alg

  7. Setting Up Pointers • In Ada we can define a type access My_Type and declare the pointer to be of that type • Can do similar in C but more usual to use: my_type *pntr; • This declares *pntr to be of type my_type and therefore implicitly pntr must be a “pointer-to-a-my_type” • Ca and C++ use pointers a lot - they are analogue of raw memory address in Assembler/Machine code. Powerful and efficient - but responsibility for not getting lost in memory lies with the programmer! Prog Lang & Alg

  8. Note the use of pointer references for left and right Some mutual recursion is needed to set all this up! The language systems cope with it, luckily. Prog Lang & Alg

  9. Allocation to A Pointer • In C: bin_tree_type *btptr = NULL; • Standard way to correctly initialise a pointer • We can allocate an actual item using: btptr= (bin_tree_type * )malloc( sizeof( bin_tree_type) ); • Ada allows new Bin_Tree_Type • Similar syntax in C++ and Java • Remember the pointer is just a data item or variable that contains an address • NULL means “no-address” or the “address of no-thing • Malloc() returns a memory address of a freshly allocated piece of memory, or NULL if it fails. (Good code will check this) Prog Lang & Alg

  10. More Pointer Lore • Copying a pointer involves copying one small address - much faster than copying a huge data structure • In C we use: &x to obtain the address of any data item x • A “pointer-to-a-my-type” can hold the address of any actual item of type “my_type” • We can have pointers to pointers to pointers… • In C pointers used as a substitute for some of the uses of a reference/alias - but they are different ideas • Some languages like C also let you do arithmetic on pointers - treating them as real memory addresses Prog Lang & Alg

  11. Note that in the C code the & is on the RHS of the equals -it is therefore the address operator (not the referencer as in C++) As usual, Ada has more verbose but clearer syntax than C. Prog Lang & Alg

  12. Dangling References • Some languages have automatic garbage collection like Java so you do not need pointers • In C, C++ you need to do your own dynamic memory management • Using either: malloc/free calls (C ) • Or new/delete operators (C++) • Be careful to free-up or delete allocated memory when you are finished using it or your program will leak memory • Be also careful to nullify all pointers that point to any memory that has been free’d or deleted • Otherwise they are said to be dangling pointers Prog Lang & Alg

  13. C++ code can use reference mechanism - note the & is in a different place than for address operator in C It is unfortunate that we talk about “de-referencing” a pointer - it is a different idea from a reference. Prog Lang & Alg

  14. Look No Pointers! • Other languages like SETL, ABC and Orca have not and do not need pointers • Instead they supply inbuilt implementations of the data structures we would need pointers for. (eg lists, tables, sets and graphs…) • Unfortunately such language s either do not emphasise efficiency or require optimising compilers • Note also that pointers are only valid inside one machine - they are meaningless across a network (in a distributed program for example) Prog Lang & Alg

  15. Unions • A union is like a struct of N fields where the one value of the data item of the union type can be any of the N fields • A compiler typically use s the same overlapping memory space for all the N fields - can give odd results • Useful in “the bad old days” when we needed to save memory in programs (computer had small memories) • Still of some use when we want to mess around at the bits/bytes level of some data item Prog Lang & Alg

  16. A garage can contain either: a car; or a number-of-bicycles Note that Ada has extra status information (discriminated union). In C the programmer has to remember which field is valid at any given time! (known as an undiscriminated union ) Prog Lang & Alg

  17. Union Type Safety • In languages cases like C which supply an undiscriminated union construct it is not possible to do strong type checking • In Ada each access of its discriminated union data is checked for consistency. • A tricky example is unioining floating point numbers. Usually these now conform to an IEEE standard (754). Not all bit patterns are valid however, so if we union an int with a float in C, we may end up with invalid float values. Prog Lang & Alg

  18. Routines as Data Types • Some languages allow routines (procedures and functions) to be used as ordinary values (with appropriate restrictions) • Why is this useful? • So we can have for example an array of functions and decide which one to call dynamically at run time depending upon some data value - eg a key-press character • Both C and modern Ada allow us to have pointers to routines - known as function pointers in C Prog Lang & Alg

  19. C: int (*convert_to_int) (float); Declares a variable called convert_to_int of type “pointer to a function which returns an int and takes a single float argument” i = convert_to_int( 3.14); implicit dereferencing done, or i = (*convert_to_int)(3.14); Explocit dereferencing also allowed. Ada: type R2I_Access_Type is access function (F:float) return Integer; Convert_To_Int: R2I_Access_Type; I = Convert_To_Int( 3.14); I = Convert_To_Int.all(3.14); Prog Lang & Alg

  20. #include <iostream> #include <fstream> #include <string> #include <iomanip> #include <typeinfo> #include <math.h> #include <ctype.h> using namespace std; void some_function( void *ptr ){ cout << "some_function called " << endl; char * message; message = static_cast<char *>( ptr ); cout << message << endl; } void indirect( void (*f)(void *), void *pt ){ (*f)(pt); } int main(int argc, char *argv[]){ char *message1 = "A message"; void (*fp1)(void *); fp1 = some_function; indirect( fp1, (void *) message1); exit(0); } Here is an example of a function pointer being used in C++ Void pointers can hold “anything” but are only to be used to ferry around other pointers - they have to be cast into an appropriate type before use. You might use this to write your own library function (indirect) that can do things with arbitrary functions passed to it at runtime. Prog Lang & Alg

  21. Orthogonality of Data Types & Declarations • In principle all the type constructors we have discussed can be combined and applied in any combination • We can have arrays of records, records containing arrays, or sets of pointers to unions… • In practice not all combinations are supported by all languages • We say two features are orthogonal if they can be combined freely without in any way restricting one another • The word orthogonal comes from Greek word for “perpendicular” - metaphor of perpendicular axes Prog Lang & Alg

  22. Kinds of Orthogonality in Languages • Combination Orthogonality (if a combination allowed for one pair then it should be for all…) • Sort Orthogonality (if one is allowed then all is also) • Number Orthogonality (if one, then zero or more should be allowed) • These principles if obeyed make the language cleaner (more consistent) and easier to both remember and understand for the programmer and compiler writer • Orthogonality is an important language design principle • It forbids unexpected exceptions • First used explicitly in design of Algol 68 - one reason for algol’s importance in the history of programming languages Prog Lang & Alg

  23. Combination Orthogonality • If one member of a sort S1 can be combined meaningfully with one member of a sort S2, then any member of a sort S1 can be combined meaningfully with any member of a sort S2. • For example, of the three data declaration kinds: plain; initialising and initializing constant declarations… • Combination orthogonality for declarations and types states that any kind of declaration can be used for any kind of type. • C violates this in a few places - eg no initialising declarations of unions are allowed. Ada upholds it quite well. Prog Lang & Alg

  24. Sort Orthogonality • In any circumstance in which one member of sort S is allowed meaningfully, any member of sort S is allowed meaningfully. • For example, if a language has records containing basic types it should allow records containing arrays, or records-containing records • Both C and Ada follow this principle faithfully Prog Lang & Alg

  25. Number Orthogonality • In any circumstance in which one member of sort S is allowed meaningfully, zero or more members of sort S are allowed meaningfully. • For example, where one declaration is allowed, zero or more declarations should be allowed. • Actually this often requires some syntactic support to allow more than one statement where only one is expected - eg curly brackets { }’s used for blocks of statements • Ada has a special record field null; used for a record with no fields. Prog Lang & Alg

  26. Restricted Types • Sometimes we use types for purpose s for which they are not ideal - eg integers for indexes - not all values will be valid (in bounds) • So we need array bounds checking • Languages that do support value-restricted type s usually only do it in a simple way - eg to a single contiguous range • Only way to enforce a complicated restriction is to implement the type as an abstract data type (ADT) • Sometimes we also need to restrict possible operations on a type - again only use of an ADT is a sound approach Prog Lang & Alg

  27. Type Equivalence • Strong type checking raises question of when two types are equivalent • Is the type of an integer array whose bounds ranges from 1 to 12 the same as the type of a shorter array whose bounds are 1 to 11 ? • Is a type apples defined as an integer equivalent to a type pickles also defined as an integer? • Would the programmer really want to mix them in arithmetic expressions? • Is the union of an integer and a real the same as the union of a real and an integer? Prog Lang & Alg

  28. Two kinds of equivalence issues: • Structural equivalence • Two types are the same if their value sets and operators are the same • So apples and pickles are the same under this • Also order of types in a union do not matter • Name equivalence (stronger requirement) • Requires that every type has a name and: • Simple rule - two types are name equivalent if and only if their names are the same • So apples and pickles are not name equivalent • Algol68 adheres strictly to structural equivalence • In C name equivalence is used for records and unions but structural equivalence is used for the rest of the language Prog Lang & Alg

  29. Coercions, Contexts, Casts & Conversions • Strong type checking (our goal) asks : • If in some context we expect an object of type T1 but we find an object of type T2 - is this acceptable? • Not so demanding as requiring type equivalence • we can perhaps find a way to cope with the indiscrepancy through a type coercion or cast • Example - “we expect a real but find an int” - we can often safely promote an int to a real but the opposite is not safe as it will truncate precision Prog Lang & Alg

  30. The language designer can force conversions to be explicit • Or allow the compiler to insert some type conversion code implicitly if context is clear enough - known as a coercion • If context is not adequate it can be strengthened in some languages by specifying the required type explicitly as a cast • In C:int i; float f = 3.14; i = (int) f + 5; i gets end value of 8 • No casts allowed in Ada • conversion is even more explicit and relies on calling some conversion function - used extensively in Ada • Coercions can obscure errors eg = and == typoes Prog Lang & Alg

  31. Data & Data Declarations Constant Declarations Uninitialized variables Renaming & Aliasing Overloading Types and Type Constructors Enumeration Types Arrays Sequences Sets & Bags Records & Pointers Unions Routines as Data Types Orthogonality of Data Types & Declarations Restricted Types Type Equivalence Coercions, Contexts, Casts & Conversions Bal & Grune Chapter 2 - Sections 2.1 and 2.2 Sebesta Chapters 5 & 6 Imperative - Parts 1& 2 - Summary Prog Lang & Alg

More Related