Linkable classes

So, I'm reviewing a program on pages 193-195 of C++ for dummies, 6th edition. [o
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
// LinkedListData - store data in a linked list of objects
#include <cstdio>
#include <cstdlib>
#include <iostream>
#define NULLPTR 0   // use nullptr when supported

using namespace std;

// NameDataSet - stores a person's name (these objects
//               could easily store any other information
//               desired).
class NameDataSet
{
  public:
    string sName;

    // the link to the next entry in the list
    NameDataSet* pNext;
};

// the pointer to the first entry in the list
NameDataSet* pHead = NULLPTR;

// add - add a new member to the linked list
void add(NameDataSet* pNDS)
{
    // point the current entry to the beginning of
    // the list
    pNDS->pNext = pHead;

    // point the head pointer to the current entry
    pHead = pNDS;
}

// getData - read a name and social security
//           number; return null if no more to
//           read
NameDataSet* getData()
{
    // read the first name
    string name;
    cout << "Enter name:";
    cin  >> name;

    // if the name entered is 'exit'...
    if (name == "exit")
    {
        // ...return a null to terminate input
        return NULLPTR;
    }

    // get a new entry and fill in values
    NameDataSet* pNDS = new NameDataSet;
    pNDS->sName = name;
    pNDS->pNext = NULLPTR; // zero link

    // return the address of the object created
    return pNDS;
}

int main(int nNumberofArgs, char* pszArgs[])
{
    cout << "Read names of students\n"
         << "Enter 'exit' for first name to exit"
         << endl;

    // create (another) NameDataSet object
    NameDataSet* pNDS;
    while (pNDS = getData())
    {
        // add it to the list of NameDataSet objects
        add(pNDS);
    }

    // to display the objects, iterate through the
    // list (stop when the next address is NULL)
    cout << "\nEntries:" << endl;
    for(NameDataSet *pIter = pHead;
                       pIter; pIter = pIter->pNext)
    {
        // display name of current entry
        cout << pIter->sName << endl;
   }

    // wait until user is ready before terminating program
    // to allow the user to see the program results
    system("PAUSE");
    return 0;
}


I'm getting confused in main(). On line 69, it's supposed to break out of the loop if getData() returns a null according to the book. But it's not if it returns a null. It's just if the address of pNDS equals the one returned by getData. So, if I were to type "exit" right away in the program, I would think it would keep the loop going, since pNDS would be uninitialized. I added cout << pNDS; before the first loop and apperently, it's initialized to 0x2 instead of zero. I then tried removing the null initializer for pHead and putting cout << pHead; and it was still 0. What's going on there?
I'm getting confused in main(). On line 69, it's supposed to break out of the loop if getData() returns a null according to the book. But it's not if it returns a null. It's just if the address of pNDS equals the one returned by getData.


Incorrect. = is assignment. == is comparison.

On line 69 pNDS is set to the value returned by getData. This value is then tested in the while conditional.

Last edited on
Look closely, there's only one "=" sign. An equality test would use 2 : "=="

This loop's code uses 2 little tricks rarely taught to beginners:

1) In C, you can test the result of any expression that returns something, and an assignment operation returns the assigned value.
It's often used when you need to check the return value of a function and use that value later. If you could not do that, it would be a little messier to write the same thing.
In short, the loop of your example is the equivalent of this:
1
2
3
4
5
6
7
8
9
NameDataSet* pNDS = getData();
while ( pNDS )
{
    // add it to the list of NameDataSet objects
    add(pNDS);
    
    // create another NameDataSet object
    pNDS = getData();
}


2) In C/C++, the ifs and while in fact consider the test succeeds if the result of your condition is different from 0. For example, if you write if( a == b ), (a == b) is in itself an expression that returns 1 if they are equal or 0 otherwise.
As a consequence it's become usual amongst experienced programmers not to explicitly write the condition when it's simply a comparison to 0: if( a != 0 ) becomes if( a ).
Using what I explained in 1), the loop of you example could then be written:
1
2
3
4
5
6
7
8
9
NameDataSet* pNDS = getData();
while ( pNDS != 0 // 0 or NULLPTR )
{
    // add it to the list of NameDataSet objects
    add(pNDS);
    
    // create another NameDataSet object
    pNDS = getData();
}


It's a bit surprising they used these tricks in a beginner's book without explaining them.
It also makes their definition of NULLPTR useless

Last edited on
THANK you! Makes a lot more sense now! ^^
Topic archived. No new replies allowed.