Understanding my pointer...

Started by
3 comments, last by rip-off 16 years, 2 months ago
First off I understand that we are not to post homework questions however this is a finished assignment (as you can see by the code) that I had a few questions on. I have the following code and it is just to utilize the methods that I created, however I do not quite understand the pointer and why exactly it only works with the pointer. I am assuming it has something to do with the arrays. I already read through my usual resources but it just isn't clicking. Here is the code, the pointer is in the class;

#include <iostream>
#include <string>

using std::cout;
using std::cin;
using std::endl;
using std::string;

class ArrayClass
{
private:

public:

	int *publicArray; 
	int publicArraySize;

	ArrayClass(int[], int);
	int sum(void);                 //Adds the array elements together
	int countNumbersBigger(int);   //Counts how many numbers in the array are larger then the given value
	int average(void);             //Displays the average of the array elements (truncated).
	int high(void);                //Displays the highest array element.
	int low(void);                 //Displays the lowest array element.
	int find(int);                 //Finds and returns the subscript of the number entered in the parameter.
};

ArrayClass::ArrayClass(int AnArray[], int ArraySize)
{
	publicArray     = AnArray;
	publicArraySize = ArraySize;
}

int ArrayClass::low(void)
{
	int lowValue = publicArray[0];

	for(int i = 0; i < publicArraySize; i++)
	{
		if(publicArray < lowValue) 
		{
			lowValue = publicArray;
		}
	}
	return lowValue;
}

int ArrayClass::high(void)
{
	int highValue = publicArray[0];
	for(int i = 0; i < publicArraySize; i++)
	{
		if(publicArray > highValue)
		{
			highValue = publicArray;
		}
	}
	return highValue;
}

int ArrayClass::average(void)
{
	int sumOfArray = 0;
	int averageOfArray = 0;

	for(int i = 0; i < publicArraySize; i++)
	{
		sumOfArray += publicArray;
	}
	averageOfArray = (sumOfArray/publicArraySize);
	return averageOfArray;
}
int ArrayClass::find(int number)
{
	int row = 0;
	while(row < publicArraySize && publicArray[row] != number)
	{
		row +=1;
	}
	
	if(row < publicArraySize)
	{
		return row;
	}

	else
	{
		cout<<"\nError, that is not a valid selection.\n";
		return 0;
	}
}

int ArrayClass::countNumbersBigger(int number)
{
	int count = 0;

	for(int i = 0; i < publicArraySize; i++)
	{
		if(number <= publicArray)
		{
			count += 1;
		}
	}
	return count;
}


void main()
{
	int myArray[]={45,654,32,3044,432,332,24,239,643,9214};
	int arraySize;

	arraySize = (sizeof(myArray)/sizeof(myArray[0]));

	ArrayClass scottArray(myArray, arraySize);;

	cout<<"Test"<<endl;

	cout<<scottArray.publicArray[332]<<endl<<endl;

	cout<<"Low: "<<scottArray.low()<<endl;
	cout<<"High: "<<scottArray.high()<<endl;
	cout<<"Average: "<<scottArray.average()<<endl;
	cout<<scottArray.find(332)<<endl;
	cout<<"Bigger Number: "<<scottArray.countNumbersBigger(500)<<endl;

}

My theory is that because ArrayClass is initialized with an array as an argument that that is why I need to have a pointer but I cant confirm this. I also don't quite understand the benefit of a pointer over a regular variable. I ordered some more books to clarify this but they wont get here for awhile so any help would be greatly appreciated. Thank you.
Advertisement
My apologies.

Pointer references:
http://www.gamedev.net/reference/articles/article1697.asp
http://www.gamedev.net/reference/articles/article1930.asp
http://www.gamedev.net/reference/articles/article1869.asp

[Edited by - Justin Rebuilt on February 15, 2008 9:26:21 AM]
Quote:Original post by Justin Rebuilt
An array is just a pointer to the beginning of a contiguous block of memory. Using int[] Array is the same as int* Array.


Except it isn't.

@OP: the benefit of a pointer is demonstrated in your program.
You have an array in main, and you refer to it indirectly in your array class. The alternative would be to copy the array. Imagine if the array were large, say a few thousand million or more elements. You've saved yourself that much memory by not making a copy.

This is one benefit of indirect referencing. An important point to note is that indirect referencing can be achieved in an alternative manner in C++, that is using a C++ reference. These are demonstrated in the linked thread above - but don't worry about the funky syntax, that is because references to an array are hard. However, a reference to some other type is easier:
void passByPointer( int *a ){    assert(a != NULL);    *a = 24;}void passByReference( int &a ){    a = 42;}int main(){    int i = 0;    std::cout << i << '\n'; // prints  0    passByPointer(&i);    std::cout << i << '\n'; // prints  24    passByReference(i);    std::cout << i << '\n'; // prints  42}


On another note, the array class is a demonstration of "over engineering". In C++, it would be idiomatic to write the various array functions as free functions (in fact, the Standard C++ Library provides most of those functions (called algorithms, in the <algorithm> header) for you, and can be used with ordinary arrays or complex container classes).

This line is an error:
cout<<scottArray.publicArray[332]<<endl<<endl;


Using array index notation [] this will yield the 333th* element in this array. Note: the array is only 10 elements long! To print the element with the value 332, you need to index the array with the 6th* element, or scottArray.publicArray[5].

* remember, arrays indices start with 0.

[Edited by - rip-off on February 15, 2008 9:28:38 AM]
Wow thank you guys so much for both of your replies. That does make sense now to just use a pointer instead of copy. My book doesn't explain why to use a pointer. I printed out those sheets so I have some reading and practicing to do tonight.

Also its a shame in my haste that I didn't reread my code before I turned it in lol. I have no clue why that line is in there. I should have deleted it. Oh well live and learn right?

So would it be a safe assumption to say that when dealing with large amounts of data always use pointers?
Quote:Original post by Chrono1081
Wow thank you guys so much for both of your replies. That does make sense now to just use a pointer instead of copy. My book doesn't explain why to use a pointer. I printed out those sheets so I have some reading and practicing to do tonight.

Also its a shame in my haste that I didn't reread my code before I turned it in lol. I have no clue why that line is in there. I should have deleted it. Oh well live and learn right?

So would it be a safe assumption to say that when dealing with large amounts of data always use pointers?


Actually, using raw pointers is rather rare when dealing with large programs. They are unsafe and often the cause of errors. Instead, C++ programmers have a variety of techniques to make the idea of pointers easier:

The three main uses of pointers are:

0) Indirect referencing
1) Dynamic Memory Allocation (single)
2) Dynamic Memory Allocation (container)

For 0, the usual scenario is passing some potentially large object to a function. If the function is to modify the object in place, we use a C++ reference. This uses the ampersand character as shown in my earlier post. If the function doesn't modify the object, we pass a const C++ reference. This prevents us accidentally modifying the object. For example, an idiomatic function taking a standard C++ string object is written:
void foo( const std::string &arg ){   // ...}


Sometimes, we want optional arguments. Pointers are a reasonable way of implementing this, we can treat a NULL pointer as "no argument passed". With default values this can be quite convenient. We could also use boost::optional<> or something. But see below before choosing a raw pointer.

For both one and two, an important issue is ownership. Consider a dynamically allocated object. We must delete it, otherwise we will have a memory leak. But who should delete it? Sometimes it is obvious, sometimes it isn't. We call the object who is responsible for deleting a pointer the owner.

1) In C++ we love values. Pointers are messy. However, sometimes one has to deal with pointers to objects. For example, sometimes we want to store objects in a container, but cannot copy construct them (an example might be a networked program: if one had a "socket" type, it does not make sense to copy them). We can however, copy pointers to these objects. However, this brings us back to dealing with messy pointers which could accidentally be uninitialised, or NULL, or we may forget to delete them. In this case, the best solution would be to use smart pointers. The Standard C++ Library contains a single smart pointer type, std::auto_ptr<>. This isn't widely used as it has somewhat confusing copy semantics. std::auto_ptr<> acts like a pointer, and will delete the "pointed at" thing when it goes out of scope. However, std::auto_ptr<> transfers ownership when it is copied, which is confusing (for example, if one passed an auto_ptr by value to a function, the callee's auto_ptr<> would become null and the one in the function would delete the pointee when the function exited).

The boost library has a number of smart pointers which can express ownership semantics. The most common is boost::shared_ptr<>. This object allows more than one pointer variable share a pointee. The pointee is deleted when the last shared_ptr<> referencing it goes out of scope.

2) In general, one will never call new [] and delete [] directly in a C++ program. At the very least, std::vector<> can be used as a thin wrapper around new [] and delete []. However, there are a variety of different containers to choose from, with different performance characteristics. std::vector is a dynamic array, so it is fast for iterating over, and fast for random access. std::list, as a linked list, is fast for insertion at any point, but iteration is marginally slower, and random access is not directly supported (being an O(n) operation).

I hope this shows some of the powerful alternatives to raw pointers. Some may be beyond you for the moment, but don't worry. I remember the time all these std::auto_thingies and boost::shared_crazies were strange things to me too, but if you are serious about wanting to be a good C++ programmer, you'll use them eventually and they will help you.

This topic is closed to new replies.

Advertisement