+ All Categories

CS 1312

Date post: 01-Jan-2016
Category:
Upload: barry-palmer
View: 22 times
Download: 1 times
Share this document with a friend
Description:
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 - PowerPoint PPT Presentation
59
CS 1312 CS 1312 Introduction to Object Oriented Programming Lecture 25 C & Pointers Structs Preprocessing
Transcript

CS 1312CS 1312

Introduction to

Object Oriented Programming

Lecture 25

C & Pointers

Structs

Preprocessing

Bits, Bytes and WordsBits, 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.

Conceptual MemoryConceptual 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;

We write:int someInt;someInt = 7;

Conceptual MemoryConceptual Memory

Memory Address Contents Symbol

or Identifier

2000 7 someInt

Technically this only

exists up

through compilation.

Strictly SpeakingStrictly 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.

More MemoryMore Memory

ADDR CONT SYMB

1000 2000 pint

2000 7 ix

2004 42 iy

2008 -17 iz

• 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

Initializing ItInitializing It

ADDR CONT SYMB

1000

2000 7 ix

2004

2008

• The codeint ix = 7;

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.

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.

Assigning to itAssigning to it

ADDR CONT SYMB

1000

2000 7 ix

2004 ? iy

2008 ? iz

• The codeint ix = 7;

int iy, iz;

Assigning to itAssigning to it

ADDR CONT SYMB

1000

2000 7 ix

2004 42 iy

2008 ? iz

• The codeint ix = 7;

int iy, iz;

iy = 42;

Assigning to itAssigning to it

ADDR CONT SYMB

1000

2000 7 ix

2004 42 iy

2008 -17 iz

• The codeint ix = 7;

int iy, iz;

iy = 42;

iz = iy - 59;

A Pointer at last!A Pointer at last!

ADDR CONT SYMB

1000 pint

2000 7 ix

2004 42 iy

2008 -17 iz

• The codeint *pint;

Possible Points of Confusion1. The pointer is named pint not

*pint2. It is not necessarily the size

of an int rather it is pointing to an int. Important in a minute.

Possible Points of Confusion1. The pointer is named pint not

*pint2. It is not necessarily the size

of an int rather it is pointing to an int. Important in a minute.

Can also be written as... int* pint

Make it point!Make it point!

ADDR CONT SYMB

1000 2000 pint

2000 7 ix

2004 42 iy

2008 -17 iz

• The codeint *pint;

pint = &ix;

DereferencingDereferencing

ADDR CONT SYMB

1000 2000 pint

2000 8 ix

2004 42 iy

2008 -17 iz

• The codeint *pint;

pint = &ix;

*pint = 8;

Syntax Note

int *pint;

Means that when pint is dereferenced it will be pointing

to an int

Syntax Note

int *pint;

Means that when pint is dereferenced it will be pointing

to an int

DereferencingDereferencing

ADDR CONT SYMB

1000 2000 pint

2000 50 ix

2004 42 iy

2008 -17 iz

• The codeint *pint;

pint = &ix;

*pint = 8;

*pint += iy;

Fasten Your Seat Belt!Fasten Your Seat Belt!

ADDR CONT SYMB

1000 ???? pint

2000 50 ix

2004 42 iy

2008 -17 iz

• The codeint *pint;

pint = &ix;

*pint = 8;

*pint += iy;

pint += 1;

was 2000

Fasten Your Seat Belt!Fasten Your Seat Belt!

ADDR CONT SYMB

1000 2004 pint

2000 50 ix

2004 42 iy

2008 -17 iz

• The codeint *pint;

pint = &ix;

*pint = 8;

*pint += iy;

pint += 1;

Why do they call it notorious pointer

arithmetic?

Why do they call it notorious pointer

arithmetic?

Pop QuizPop 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?

Pop QuizPop 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

Hilarious ImplicationsHilarious 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

But we can fool the computer!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 actuallycreate any pointer variablesin our calling sequence.

2. We don’t change a and b inside of swap just what they are pointing to...

Notice 1. We didn’t actuallycreate any pointer variablesin our calling sequence.

2. We don’t change a and b inside of swap just what they are pointing to...

Pop QuizPop 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

Which one goes here to print 3?

b*b&b

Pop AnswerPop 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;

}

Pop QuizPop 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

b Pointer to an int*b What b is pointing at&b Address where b is stored

Now it gets...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];

Strange and Wonderful Thing IStrange 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;

}

Strange and Wonderful Thing IIStrange 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;

}

Strange and Wonderful Thing IIIStrange 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]

CautionCaution

• 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”

““Actual Array”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!!!!!!!!!!!!!!!!!

Allocating MemoryAllocating 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 thata. You got it and where it’s located

OR

b. You didn’t get it

• The feared and dreaded

void *malloc(size_t n)

PseudomemoriesPseudomemories

• Remember the newnew function in Pseudocode?

• You said: current <- new(Node)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.

Warning, Danger, Will RobinsonWarning, 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! ;-)

Simple MallocSimple Malloc

• Let’s say you want space for 100 ints.• Here is what you do:

int *pintpint = (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;}

Going crazy?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?

VisuallyVisually

ADDR CONT SYMB

1000 ?? x

2000 ??

3000 ??

int x;

VisuallyVisually

ADDR CONT SYMB

1000 ?? x

2000 ?? px

3000 ??

int x;

int *px;

VisuallyVisually

ADDR CONT SYMB

1000 ?? x

2000 ?? px

3000 ?? ppx

int x;

int *px;

int **ppx;

VisuallyVisually

ADDR CONT SYMB

1000 ?? x

2000 1000 px

3000 ?? ppx

int x;

int *px;

int **ppx;

px = &x;

VisuallyVisually

ADDR CONT SYMB

1000 ?? x

2000 1000 px

3000 2000 ppx

int x;

int *px;

int **ppx;

px = &x;

ppx = &px;

VisuallyVisually

ADDR CONT SYMB

1000 42 x

2000 1000 px

3000 2000 ppx

int x;

int *px;

int **ppx;

px = &x

ppx = &px;

**ppx = 42;

Stringing You AlongStringing 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”;

Watch this closelyWatch 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 */

Over the top!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?

ImagineImagine

• 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

We have an array of pointersWe have an array of pointers

Leahy, Bill

Smith, David

Dagon, David

Morales IV, Ricky Martin

name[0]

name[1]

name[3]

name[2]

And we just move the pointers in the And we just move the pointers in the array to sortarray to sort

Leahy, Bill

Smith, David

Dagon, David

Morales IV, Ricky Martin

name[0]

name[1]

name[3]

name[2]

More funMore fun

• 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));

...

names 01

29

Pointersto chars

Running with the big dogsRunning 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;

};

More structsMore 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;

};

Putting it all togetherPutting 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));

One last thingOne last thing

• C allows you to make up your own type identifiers using typedef

• This is used as follows with struct definitions

typedef struct Node

{

int data

struct Node *next;

} Node;

• Now we can say

Node *head

Questions?Questions?

PreprocessingPreprocessingCompilation begins by moving the C source files through a preprocessor--a simple text substitution device.

One can designate strings for substitution with the expression:

#define <expression> <substitute>#define <expression> <substitute>

#include <stdio.h>#define GREETING “Hello World”

int main ( void ) {

printf (GREETING);

}

int main ( void ) {

printf (“Hello World”);

}

The C preprocessor has many features--and pitfalls.

#define g(y) get_index(y)g(z)

#define g (y) get_index (y)g(z)

A Tale of Two ExpansionsA Tale of Two Expansions

get_index(z)

(y) get_index (y) (z)

Notice the extrawhite space

This is knownas “macro substitution”

The Power of ParensThe Power of Parens

#define DIVIDE(x, y) x/y

DIVIDE(3, 3+4) 3/3+4

#define DIVIDE(x, y) (x)/(y)

DIVIDE (3, 3+4) (3)/(3+4)

Inputs Results

More SubstitutionMore Substitution

#define square(x) x * x#define square(x) x * x

What’s wrong with this?

It could be called thus:

square (z + 4)square (z + 4)

Resulting:

z + 4 * z + 4z + 4 * z + 4

And not:

(z+4) * (z+4)(z+4) * (z+4)

Common Sense PreprocessingCommon Sense Preprocessing

11 Watch extra white space, as shown in the previous examples.

22 Liberally use parentheses to protect order of precedence

Questions?Questions?


Recommended