?
Solved

Why we do not need pointer for this addres book program

Posted on 2003-03-31
6
Medium Priority
?
281 Views
Last Modified: 2010-04-01
Hi All the Experts,

Good Morning!
I come across a program online and have some doubts on the use of pointer. For the code AddressBook.cpp below, it does not use pointer for the following variables
    char name[30];
    char phone[13];
    char email[30];
    int srchtype;
    char srchstr[30];
However, for File , is use pointer to char like the following;
    char* File;

I wonder why we do not need pointers this the first case and why we need pointer for the latter? Can any expert help me on this. I really wish to know how one can determine when must we use pointer.
In my mind , what I have read from book is that for any variable that pass into a function, we need to use pointer in order to retain the new modified value. So in this code, why name, phone, email are not in pointer form as many functions are involved here? We will have many particulars in our address book and each particular has different name, phone and email, so why this code still work without pointer? I really confused.

I borrowed a book from library and the code is too long, it used pointer to carry out the same function. But I am interested to know why this code can retain and print each different name, phone and email when pointer is not used. Kindly enlighthen me.

I am sorry for any inconvenience caused.

Hear from you all soon.

Thank you very much


best regards
Jason
-------------------------
Addressbook.cpp
-------------------------
#include <fstream.h>
#include <cstring>
#include <cstdio>



class book {
  //these are only visible by class book and its member functions
  private:
    int choice;
    char* File;
    char name[30];
    char phone[13];
    char email[30];
    int srchtype;
    char srchstr[30];

  //these are visible to book objects
  public:

    //this constructor is called whenever an object of
    //class book is created to initialize our variables
    book() { File="addresses.dat"; choice = 0; };

    //function prototypes
    void ShowBook();
    void AddEntry();
    int Menu();
    void Print();
    void SearchMenu();
    bool Found(book&);

    //some helper functions
    void Flush() { while (cin.get() != '\n') cin.get(); }
    bool CheckOpen(fstream &f) {
      if (!f.is_open()) {
        cerr << "\nError opening " << File << endl;  
        return false;
      }  
      return true;
    }      
};

/* the MAIN function */
int main() {
  book b;

  while (b.Menu())
    ;
 
  return 0;
}

/* member function definitions */
int book::Menu() {  
  cout << "\n1. Add Contact\n"
          "2. Show Contacts\n"
          "3. Exit\n\n"
          "Choice: ";
  cin >> choice;
 
  switch (choice) {
    case 1:      AddEntry(); break;
    case 2:      ShowBook(); break;
    case 3:      choice = 0; break;
  }
  return choice;
}

void book::AddEntry() {
  fstream fout(File,ios::end|ios::app|ios::binary);

  if (!CheckOpen(fout))
    return;
  else {    
    Flush();
    cout << "\nEnter contact name: ";
    cin.getline(name,30);
    cout << "Phone number: ";
    cin.getline(phone,13);
    cout << "Email address: ";
    cin.getline(email,30);
 
    fout.write((char*)this,sizeof(*this));
    fout.close();
  }
}

void book::ShowBook() {
  fstream fin(File,ios::in|ios::binary);
  book temp;

  if (!CheckOpen(fin))
    return;
  else {
    SearchMenu();
    bool foundmatch = false;
    cout << "\n----- DISPLAYING CONTACTS -----\n";
    while (fin.read((char*)&temp,sizeof(temp)) && !fin.eof()) {
      if (Found(temp)) {
          temp.Print();
          foundmatch = true;
      }
      else if (srchtype == 4) {
        temp.Print();    
        foundmatch = true;
      }
    }    
    if (!foundmatch)
      cout << "\nNo matching entries found!\n";
    cout << "\n----- FINISHED DISPLAYING -----\n";
    fin.close();
  }
}

void book::Print() {
    cout << "\n  Name: " << name << endl;      
    cout << " Phone: " << phone << endl;
    cout << " Email: " << email << endl;
}

bool book::Found(book &temp) {
  if (srchtype == 1 && strstr(temp.name,srchstr) ||
      srchtype == 2 && strstr(temp.phone,srchstr) ||
      srchtype == 3 && strstr(temp.email,srchstr))
    return true;
  return false;
}

void book::SearchMenu() {
  cout << "\nSearch by:\n"
          "1. Name\n"
          "2. Phone#\n"
          "3. Email\n"
          "4. Show All\n\n"
          "Choice: ";
  (cin >> srchtype).get();
  if (srchtype != 4) {
    cout << "Enter the search value: ";
    cin.getline(srchstr,30);
  }
}
0
Comment
Question by:jason_class
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
6 Comments
 
LVL 1

Expert Comment

by:igor_sk
ID: 8239724
Take a look on 'book' constructor. First argument is a pointer to array of char. It defines filename. It is initialized in some other function and passed into 'book' constructor as argument. The default value of this argument is "addresses.dat".

Why File is a pointer? Because this is a way of passing array to the function.

When you define an array as
char myarray[32];

and then call some function as
myfunction(myarray);

you actually pass an address of myarray to myfunction.

Hope this will help you.
0
 
LVL 12

Accepted Solution

by:
Salte earned 200 total points
ID: 8239819
OK,

rule number 1 about arrays and pointers:

If you declare an array of type T (T can be any type, char, int, struct, class, whatever) such as this:

T arr[N];

where N is some constant integer giving the number of elements of the array.

Then if you use the simple name 'arr' in expressions (such as when passing arguments to functions) it will in almost all cases change itself to a value of type:

T *

and the value will be a pointer to the first element of the array, so:

arr is the same as & arr[0]

where the & is the 'address of' operator in C++ and C.

This is probably the reason why you don't see pointers when used in functions that modify the arrays:

void func(T arr[])
{
   ....
}

This function can modify the array arr by writing:

arr[5] = some_expr;

as long as some_expr is an expression that can be on the right hand side of an assignment to type T this will modify the array element number 5.

in C++ and C the [] operator doesn't work on arrays but on pointers, so when you see:

arr[5] the array is converted to a pointer to the first element, so:

arr is read as & arr[0]

and this pointer is then used to evaluate, so:

arr[x] is read as *(arr + x)

so arr[5] == *(arr + 5)

if arr is a T * to an array of at least 6 elements then the above is well formed and the expression *(arr + 5) is element 5 of the array.

So, arrays and pointers are in some ways equivalent in C++ and C.

However, there are of course some differences between them. For one thing:

void func()
{
   int arr[5];
   int * arrp;

   ...
}

The first will allocate a part of the stack of size 5 int values, each of which can be reached by arr[0], arr[1], up to arr[4]. arr[5] is NOT a valid index since that is outside the array.

The int * arrp on the other hand only allocates size for the pointer and that pointer isn't pointing any well defined place at the moment - it has random contents since we didn't initialize it.

Another difference is that you can modify the pointer to point to some other location so you can write:

arrp++;

if arrp points to arr[3] before this it will pooint to arr[4] after the ++ operation.

You cannot do arr++ since arr is always fixed to point to the first element of the array arr and cannot change.

A third difference is that sizeof(arr) and sizeof(arrp) is different, sizeof(arr) == sizeof(int)* 5 and gives the size of the memory area allocated for the array. sizeof(arrp) only give size of the pointer and not to whatever buffer that array pointer might point to.

So, if you need some memory space to store some characters or integers or whatever then you need an array, if you already have them stored some place and you just need a pointer to where they are, you can declare a pointer and assign it to the value that indicates their location.

If you for example allocate storage on heap or if the variable is pointing to some literal string then you don't need an array.

char * file = "foo";

When the compiler see "foo" it will insert the text "foo" at some location in the programs data space and give the address of that location where the string is stored as the value of that expression, so you don't need to store it in an array, you can just use a pointer to point to that location.

char file[] = "foo";

Here there's no pointer involved per se, the variable file is size 4 and contain the 4 bytes 'f', 'o', 'o' and then the null byte to terminate the string '\0'.

However, if you use 'file' by itself in any expression, it will evaluate to the address of where that buffer is:

func(file + 2);

file + 2 will be a poiter to the string "o" i.e. a pointer to the 'o' which is followed by the '\0' byte.

Note that one of the classic errors done by novice C and C++ programmers is this:

void do_something()
{
   char * dst;
   strcpy(dst,"foo");
   ...
}

This function will crash, the reason is that dst is a pointer but it isn't pointing anywhere and so the string copy will crash. You can repair that by giving it some space and provided the string isn't too big for that space it is ok:

void do_something()
{
   char buf[3];
   char * dst = buf;
   strcpy(dst,"foo");
   ...
}

This will also not work properly, the reason is that we have defined buf to have room for 3 characters. "foo" is 4 characters and not 3, it also includes the terminating nul byte '\0' so if you change buf[3] to buf[4] the code above should work.

You can also change the strcpy(dst,"foo") to simply strcpy(buf,"foo") since dst and buf evaluates to the same value, they both point to the first byte of buf.

Hope this explains.

Alf
0
 
LVL 9

Expert Comment

by:owenli27
ID: 8239949
There is no big difference between using a char pinter and using char array in your source code.
For example.

    char name[30];
is same as
    char* name;
    name = new char[30];


When you use a char point, you have to dynamiclly allocate memory for it before you use it to store value(the memory will located in Heap). And free memory when no longer using it.  The char array will have memory allocated when you declare it (the memory will be in stack if it is local variable).  

When you pass parameter into a function or print out their values. Their usage is same.  
0
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 

Author Comment

by:jason_class
ID: 8245504
Hi Everyone,

Thank you all so much for helping me.
I am so glad to see all the answers. I will read through and give a deep thought on them. Please give me more time.
;)
Thanks a lot

regards
Jason
0
 

Author Comment

by:jason_class
ID: 8245854
Hi Everyone,

Thank you all so much for helping me.
I am so glad to see all the answers. I will read through and give a deep thought on them. Please give me more time.
;)
Thanks a lot

regards
Jason
0
 

Author Comment

by:jason_class
ID: 8266531
Hi Salte, Igor_sk, Owenli27,

You all help me a lot! Igor_sk started to make me understand the idea. Salte explains a lot and make things clearer. Finally Owenli27 remind me of the new operator!
I am grateful for all the help given!
Thank you all!


regards
Jason
0

Featured Post

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Unlike C#, C++ doesn't have native support for sealing classes (so they cannot be sub-classed). At the cost of a virtual base class pointer it is possible to implement a pseudo sealing mechanism The trick is to virtually inherit from a base class…
Basic understanding on "OO- Object Orientation" is needed for designing a logical solution to solve a problem. Basic OOAD is a prerequisite for a coder to ensure that they follow the basic design of OO. This would help developers to understand the b…
The viewer will be introduced to the technique of using vectors in C++. The video will cover how to define a vector, store values in the vector and retrieve data from the values stored in the vector.
The viewer will be introduced to the member functions push_back and pop_back of the vector class. The video will teach the difference between the two as well as how to use each one along with its functionality.

752 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question