1 / 59

CS 1312

CS 1312. Introduction to Object Oriented Programming Lecture 25 C & Pointers Structs Preprocessing. Bits, Bytes and Words. A bit is a binary digit which can have a value of 0 or 1

Télécharger la présentation

CS 1312

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. CS 1312 Introduction to Object Oriented Programming Lecture 25 C & Pointers Structs Preprocessing

  2. Bits, Bytes and Words • A bit is a binary digit which can have a value of 0 or 1 • A byte today is normally considered to be 8 bits but was originally designated as the smallest addressable unit of memory • Thus one could instruct the computer to store or retrieve a given byte but not a given bit. • Bytes may be grouped into words (e.g. 4 bytes) • (plus all kinds of zany combinations thereof like half-words, double words, etc.) • So words are addressed in multiples of 4 • Since the bytes are addressed by one.

  3. Conceptual Memory • Each memory cell thus has two associated numbers • Its address • Its contents • When using any symbolic language we can also associate a symbol or identifier • Example Memory Address Contents Symbol or Identifier 2000 7 someInt We write: int someInt; someInt = 7;

  4. Conceptual Memory Memory Address Contents Symbol or Identifier 2000 7 someInt Technically this only exists up through compilation.

  5. Strictly Speaking • The computer has no idea what we’re actually doing (exception see HAL in 2001) • So a given memory location such as a byte only has a limited number of possible values • Byte: 0 - 255 (00 - FF16) • It is the programmer using a programming language that can assign this byte a meaning • Unsigned numbers from 0 to 255 • Signed numbers from -128 to 127 • Characters from a typical encoding such as ASCII where for example the letter ‘A” is represented by the number 65 • Thus we could also store in memory the address of any memory location. This is known as a pointer.

  6. More Memory ADDR CONT SYMB 1000 2000 pint • Notes: • The SYMB column isn’t actually stored in memory. • In fact, neither is the column marked ADDR! • Assume that we are showing words (32 bits) • Assume ints take a word 2000 7 ix 2004 42 iy 2008 -17 iz

  7. Initializing It ADDR CONT SYMB 1000 • The code int ix = 7; 2000 7 ix Note: Where the actual values get stored depends on several factors. Since we deal with the symbols, we don’t worry about this most of the time. 2004 2008

  8. Assigning to it ADDR CONT SYMB 1000 • The code int ix = 7; int iy, iz; 2000 7 ix 2004 ? iy 2008 ? iz

  9. Assigning to it ADDR CONT SYMB 1000 • The code int ix = 7; int iy, iz; iy = 42; 2000 7 ix 2004 42 iy 2008 ? iz

  10. Assigning to it ADDR CONT SYMB 1000 • The code int ix = 7; int iy, iz; iy = 42; iz = iy - 59; 2000 7 ix 2004 42 iy 2008 -17 iz

  11. A Pointer at last! ADDR CONT SYMB • The code int *pint; 1000 pint 2000 7 ix Possible Points of Confusion 1. The pointer is named pint not *pint 2. It is not necessarily the size of an int rather it is pointing to an int. Important in a minute. 2004 42 iy 2008 -17 iz Can also be written as... int* pint

  12. Make it point! ADDR CONT SYMB • The code int *pint; pint = &ix; 1000 2000 pint 2000 7 ix 2004 42 iy 2008 -17 iz

  13. Dereferencing ADDR CONT SYMB • The code int *pint; pint = &ix; *pint = 8; 1000 2000 pint 2000 8 ix Syntax Note int *pint; Means that when pint is dereferenced it will be pointing to an int 2004 42 iy 2008 -17 iz

  14. Dereferencing ADDR CONT SYMB • The code int *pint; pint = &ix; *pint = 8; *pint += iy; 1000 2000 pint 2000 50 ix 2004 42 iy 2008 -17 iz

  15. Fasten Your Seat Belt! ADDR CONT SYMB was 2000 • The code int *pint; pint = &ix; *pint = 8; *pint += iy; pint += 1; 1000 ???? pint 2000 50 ix 2004 42 iy 2008 -17 iz

  16. Fasten Your Seat Belt! ADDR CONT SYMB • The code int *pint; pint = &ix; *pint = 8; *pint += iy; pint += 1; 1000 2004 pint 2000 50 ix 2004 42 iy Why do they call it notorious pointer arithmetic? 2008 -17 iz

  17. Pop Quiz int x, y; int *px = &x; int *py = &y; x = 7; *py = 5; py = px; *px = *px + y + *py; printf(“%d %d\n”, *px, *py); What prints?

  18. Pop Quiz int x, y; int *px = &x; int *py = &y; x = 7; *py = 5; py = px; *px = *px + y + *py; printf(“%d %d\n”, *px, *py); 19 19

  19. Hilarious Implications • Remember we only have “in” parameters in C • So we can fake it! • Let’s say we want to write a function (procedure) to swap two numbers: void swap(int a, int b) { int t; t = a; a = b; b = t; } • Doesn’t work since parameters are “in” • Pass by Value

  20. But we can fool the computer! void swap(int *a, int *b) { int t; t = *a; *a = *b; *b = t; } Called like this: int x, y; x = 3; y = 4; swap(&x, &y); Notice 1. We didn’t actually create any pointer variables in our calling sequence. 2. We don’t change a and b inside of swap just what they are pointing to...

  21. Pop Quiz #include <stdio.h> void print_num (int* x) { printf("Number: %d\n", *x); } int main (void) { int a = 3; int* b; b = &a; print_num(??); return 0; } Which one goes here to print 3? b *b &b

  22. Pop Answer #include <stdio.h> void print_num (int* x) { printf("Number: %d\n", *x); } int main (void) { int a = 3; int* b; b = &a; print_num(b); return 0; }

  23. Pop Quiz #include <stdio.h> void print_num (int* x) { printf("Number: %d\n", *x); } int main (void) { int a = 3; int* b; b = &a; print_num(b); return 0; } b Pointer to an int *b What b is pointing at &b Address where b is stored

  24. Now it gets... • C allows us to have arrays which appear to be like other languages int a[100]; • creates an array of 100 elements which can be referenced as a[0] through a[99]. • Note that an array created in this manner is truly an array • However, we can also do strange and wonderful things now like: int *b; b = a; • Note: This is the same as b = &a[0];

  25. Strange and Wonderful Thing I int main(void) { int a[10]; int *b; int i; for (i = 0; i < 10; i++) a[i] = i; b = a; /* What happens here, recall b = &a[0] */ for (i=0; i < 10; i++) { *(b+i) = *(b+i) * 2; /* And here? */ printf("%d %d\n", i, a[i]); } return 0; }

  26. Strange and Wonderful Thing II int main(void) { int a[10]; int *b; int i; for (i = 0; i < 10; i++) a[i] = i; b = a; for (i=0; i < 10; i++) { b[i] = b[i] * 2; /* Say what (kareoke)? */ printf("%d %d\n", i, a[i]); } return 0; }

  27. Strange and Wonderful Thing III int main(void) { int a[10]; int *b; int i; for (i = 0; i < 10; i++) a[i] = i; b = a; for (i=0; i < 10; i++) { i[b] = i[b] * 2; /* Aarrrgggghhhhhhhhh!!! */ printf("%d %d\n", i, a[i]); } return 0; } b[4] 4[b]

  28. Caution • Many people will say that arrays in C are just pointer manipulations but an actual array is a special thing • So while it was okay to say b = a • It would have been wrong to say a = b • Once you create a true array: int a[10]; • You shouldn’t try and assign something else to “a”

  29. “Actual Array” • In C, we can dynamically allocate memory and we’re going to just show you enough to make you incredibly dangerous. • DON’T CUT GREENLEE’S LECTURES ON THIS SUBJECT • It could be a huge mistake! • We are only telling you part of the story!!!!!!!!!!!!!!!!!

  30. Allocating Memory • There is a function in a C library which allows you to ask for some memory. You tell it how much. It tells you that a. You got it and where it’s located OR b. You didn’t get it • The feared and dreaded void *malloc(size_t n)

  31. Pseudomemories • Remember the new function in Pseudocode? • You said: current <- new(Node) • So the idea was that the size of the Node was looked up somewhere and then enough memory was allocated to hold one Node. • Malloc works sort of like that only you can ask for as much memory as you want. • Note that both return pointers.

  32. Warning, Danger, Will Robinson • This is not a complete treatment of dynamic memory management in C. • There is no automatic garbage collection in C • There is no automatic garbage collection in C • There is no automatic garbage collection in C • There is no automatic garbage collection in C • You must eventually learn • Memory allocation • Memory reallocation • Memory deallocation • From Mr. Greenlee - You’ll love it, honest! ;-)

  33. Simple Malloc • Let’s say you want space for 100 ints. • Here is what you do: int *pint pint = (int *)malloc(100 * sizeof(int)); if (null == pint) { /* You did not get the space! */ /* Handle error here -- very important */ } /* Now you have effectively an array of ints */ for (i = 0; i < 100; i++) { pint[i] = 0; }

  34. Going crazy? • Did we mention pointers to pointers? • We did this before: int x; int *px; px = &x • We can also go one (or more) step(s) further: int **ppx; ppx = &px; • Which would allow us to do things like: **ppx = 42; /* Puts 42 into x */ Ready to run back to Java yet?

  35. Visually ADDR CONT SYMB int x; 1000 ?? x 2000 ?? 3000 ??

  36. Visually ADDR CONT SYMB int x; int *px; 1000 ?? x 2000 ?? px 3000 ??

  37. Visually ADDR CONT SYMB int x; int *px; int **ppx; 1000 ?? x 2000 ?? px 3000 ?? ppx

  38. Visually ADDR CONT SYMB int x; int *px; int **ppx; px = &x; 1000 ?? x 2000 1000 px 3000 ?? ppx

  39. Visually ADDR CONT SYMB int x; int *px; int **ppx; px = &x; ppx = &px; 1000 ?? x 2000 1000 px 3000 2000 ppx

  40. Visually ADDR CONT SYMB int x; int *px; int **ppx; px = &x ppx = &px; **ppx = 42; 1000 42 x 2000 1000 px 3000 2000 ppx

  41. Stringing You Along • Since we’re talking about arrays and pointers and pointers to pointers we should briefly mention strings • Strings in C are implemented as arrays of characters • So just as you can say: int a[ ] = {0, 1, 3, 5} • and C will correctly dimension a to be a[4] • You can also say: char b[ ] = {‘t’, ‘e’, ‘s’, ‘t’, ‘\0’} • And you can even say: char c[ ] = “test”;

  42. Watch this closely char aLine[ ] = “Hi, there!”; char *pLine = “Hi, there!”; • These are similar but not the same!!! • The first actually creates space for an array of characters (11) which can be subsequently modified aLine[4] = ‘T’; • The second creates a pointer which is pointing to a string constant so that pLine[4] = ‘T’; would be undefined while pLine = aLine; pLine[4] = ‘T’; /* is okay */

  43. Over the top! • It is not only possible to have pointers to pointers but one can even use arrays of pointers! • char *name[ ] = {“Illegal”, “Jan”, ”Feb”, ”Mar”, ”Apr”, ”May”, “Jun”, “Jul”, “Aug”, “Sep”, “Oct”, “Nov”, “Dec”}; • Now for example name[2] is a pointer to the character string ‘F’, ‘e’, ‘b’, ‘\0’ • What would we do with an array of pointers?

  44. Imagine • We have some names like • Smith, David • Leahy, Bill • Dagon, David • Morales IV, Ricky Martin • Suppose we want to sort the names but we note that they are of different lengths. • Instead of running a sort algorithm which swaps the character strings around why not create an array of pointers

  45. We have an array of pointers name[0] Smith, David name[1] Leahy, Bill name[2] Dagon, David name[3] Morales IV, Ricky Martin

  46. And we just move the pointers in the array to sort name[0] Smith, David name[1] Leahy, Bill name[2] Dagon, David name[3] Morales IV, Ricky Martin

  47. More fun names 0 1 • If we define char *names[30]; we get • The following are all legal: char z; names[4] = &z; names[5] = “fred”; names[6] = (char*)malloc(20*sizeof(char)); ... 29 Pointers to chars

  48. Running with the big dogs • The classic data structure in C which is equivalent to • Records in Pseudocode (Pascal) • Classes (without methods) in Java • Whatever in Scheme (Like a list sort of...) • is called a struct • They look like this struct ordPair { int x; int y; };

  49. More structs • So we could declare struct ordPair opAlpha, opBeta; • and access them like this opAlpha.x = 7; opAlpha.y = 8; opBeta = opAlpha; • Structs are what we would use for the classic linked list node struct LLnode { int data struct LLNode *next; };

  50. Putting it all together • Here is how we could declare a head pointer: struct LLnode *head; • here is how we could get a new node dynamically head = (struct LLnode *)malloc(sizeof(struct LLnode));

More Related