Welcome, Guest. Please login or register.

Author Topic: Mr. Biehl learns C  (Read 7351 times)

Description:

0 Members and 2 Guests are viewing this topic.

Offline FluffyMcDeath

  • Hero Member
  • *****
  • Join Date: Jun 2002
  • Posts: 3440
    • Show all replies
Re: Mr. Biehl learns C
« on: April 19, 2005, 06:58:41 AM »
Quote

ottomobiehl wrote:

Pointers are my first hurdle.  I think I understand what they are and what they do but not really what to use them for.

To declare a pointer I do this:

Quote
int *i;


right?

so if I do:

Quote
int x = 5;
int *i;

i = &x;


then i will equal the memory address of x but not the value of x, right?



Correct, but unexciting. To get the value of x from the pointer you dereference the pointer thus:
e.g.
int a;
a = *i;

The '*' dereferences the pointer to give the value of what is pointed at. The value of what is pointed at can also be changed thus:

*i = 5;

Which puts 5 at the address pointed to by i.

However, imagine you have a nice big number of things you wished to pass around, like maybe a person and you wished to pass that person (or persons like it) to a collection of functions. Let's say a person has a number of attributes like:
height, weight, dayOfBirth, monthOfBirth, yearOfBirth, name, sex

Each time you wanted to pass all that stuff to a function the call would be tedious indeed.

Instead you can create a structure and just pass a pointer to the structure a la:

typedef struct {
   int height;
   int weight;
   int dayOfBirth;
   int monthOfBirth;
   int yearOfBirth;
   char * name;
   char sex;
} personT;

Note that name is a pointer to the start of a string of bytes.

The personT is now a type (like int or char) that you can use to declare variables as. Then you can set the values.

personT mrX;

mrX.height = 167;
mrX.weight = 70;
mrX.dayOfBirth = 5;
mrX.monthOfBirth = 6;
mrX.yearOfBirth = 1978;
mrX.name = "Fred X";
mrX.sex = 'M';

/* and now you can call a function that does something with persons */

printBirthday(&mrX);


and printBirthday would look something like...

void printBirthday(personT * person)
{
    printf("%s was born %d/%d/%d\n",
           person->name,
           person->dayOfBirth,
           person->monthOfBirth,
           person->yearOfBirth );
}

Note that when you are accessing members of a struct, use . (dot). When you are accessing members of a pointer to a struct use -> (arrow or points-to).




 

Offline FluffyMcDeath

  • Hero Member
  • *****
  • Join Date: Jun 2002
  • Posts: 3440
    • Show all replies
Re: Mr. Biehl learns C
« Reply #1 on: April 19, 2005, 07:19:34 AM »
But there's more....

One of the most fun things you can do with pointers is screw yourself over in mysterious and dangerous ways.

e.g.

int *bob;

*bob = 12;

You have now written the value 12 into a totally unknown location in memory. If bob is global it'll probably be 0 but it might not be. If bob is on the stack (local to a function) it could point any old place. If you have memory protection and you have written to some memory that doesn't belong to you, or is inappropriate for writing data then you will get a grim reaper. If you don't have mem protection or you get unlucky and write to memory you own, you get a mysterious and bizarre failure that doesn't seem like it is anything to do with this code and maybe only sometimes! FUN!!!

Always make sure your pointer points at something sensible before you use it. Aim THEN fire.

Also, watch out if you are pointing at stuff on the stack.

This is OK:

int func1()
{
   int val = 4;
   return func2(&val);
}

int func2 (int* val)
{
    return *val * 2;
}

val is on the stack. You get a pointer to the stack address of val. You call the next func and the stack grows, val stays where it is, you still have the address, all is fine. The answer is 8.

If you try this:

int * func1()
{
    int num = 4;
    return #
}

int func2()
{
    int val*;
    val = func1();
    return func3(val);
}

int func3(val)
{
    int brianTheStrangeNumber = 23;
    return *val * 2;
}

now the answer could be 46, or it could be twice the value of the address of num, or something else depending on how the stack frames are laid out. That's some cool stuff.