13 Replies - 1002 Views - Last Post: 03 July 2011 - 01:59 AM Rate Topic: -----

#1 E_Geek  Icon User is offline

  • D.I.C Head
  • member icon

Reputation: 45
  • View blog
  • Posts: 236
  • Joined: 20-February 11

C++ *

Posted 01 July 2011 - 06:15 AM

char *new_board()
{
    for(int i = 0; i < 9; i++) //0 - 8, 9 places
    {
        board[i] = EMPTY;
    }
    return board;
}



If I remove the * from before the function name, I am given an error about invalid conversion from char* to char.
Could somebody please explain why I need the * in place?

Edit** Was returning the board 9 times, oops :)

This post has been edited by E_Geek: 01 July 2011 - 06:19 AM


Is This A Good Question/Topic? 0
  • +

Replies To: C++ *

#2 vividexstance  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 687
  • View blog
  • Posts: 2,377
  • Joined: 31-December 10

Re: C++ *

Posted 01 July 2011 - 06:19 AM

board is an array, an array is basically a pointer to the first element in the array, by returning just a char, you would return just 1 character. It looks to me like you want the whole board, so you need to return a pointer to a char array, which is what the '*' means. THis is just my opinion, but I think it helps if you write it this way:
char* new_board()

Was This Post Helpful? 0
  • +
  • -

#3 NickDMax  Icon User is offline

  • Can grep dead trees!
  • member icon

Reputation: 2250
  • View blog
  • Posts: 9,245
  • Joined: 18-February 07

Re: C++ *

Posted 01 July 2011 - 06:40 AM

*
POPULAR

a char* is a pointer to a char.
an int* is a pointer to an int.
a double* is a pointer to a double.

So what is a pointer? A pointer is a variable that holds a memory address that lets you "refer" to some location in memory as a variable of some given type (or no particular type in the case of a void* )

So for a quick example:
#include <iostream>

using namespace std;

int main() {
    int var = 100;
    
    int* ptr = &var;
    
    cout << "var = " << var << endl;
    cout << "address of var in memory is: " << &var << endl;
    cout << "ptr = " << ptr << endl;
    cout << "*ptr = " << *ptr << endl;
    cout << "address of ptr in memory is: " << &ptr << endl;


    return 0;
}



So here I allocate an integer and give it the value 100.
Then I allocate a pointer to an integer and give it the value of, the address of var. This means that ptr will point to var.

Both var and ptr are variables of an "integral type" (i.e. integer numbers) -- one holds the value 100, and one holds some memory address but in memory they are both just variables to hold numbers.

So the output of this program when I run it is:
> "C:\CProjects\Forum Help\ptrsEasyDemo.exe " 
var = 100
address of var in memory is: 0x28ff1c
ptr = 0x28ff1c
*ptr = 100
address of ptr in memory is: 0x28ff18

> Process Exit Code: 0
> Time Taken: 00:00


THe first cout line prints the value of var, which is 100.
Next we use the & operator (address of operator) to find the address of var (0x28ff1c).

Then we print the value of ptr -- which is the same as the address of var.
when we "dereference" ptr we get the value that it points to -- i.e. the value of var or 100.
when we look at the address of ptr we get a different address than var. That is ptr is just another variable.


Pointers can be a little bit of a difficult concept but actually make much of modern computing possible. Even languages that don't "have pointers" use them quite extensively "behind the scenes" so there really is no way to avoid them.

One of the uses of pointers is when refering to a block of memory (i.e. an array). If I allocate some block of memory say 100bytes at address 0x10000, I need a way of accessing all 100 bytes.

lets say char* myarray = 0x10000.... so the value of the first char in the array is: *myarray.
The next char in the array has the address 0x10001 so if I want to access that element I might use:

*(myarray + 1) -- myarray + 1 = 0x10001 and then *(myarray+1) gives us access to the char at that address.

Well there is a shortcut. *(ptr + n) is the same as ptr[n] - these two statements are equivalent.

So myarray[1] is *(myarray+1) and gives access to the second char.
myarray[99] is *(myarray+99) == *(0x10063) gives me access to the 100'th element or the last char in my array.
Was This Post Helpful? 7
  • +
  • -

#4 E_Geek  Icon User is offline

  • D.I.C Head
  • member icon

Reputation: 45
  • View blog
  • Posts: 236
  • Joined: 20-February 11

Re: C++ *

Posted 01 July 2011 - 06:51 AM

Thanks you both very muchly. I had a basic understanding of pointers but didn't realise how arrays worked with them in c++. :)
Was This Post Helpful? 0
  • +
  • -

#5 NickDMax  Icon User is offline

  • Can grep dead trees!
  • member icon

Reputation: 2250
  • View blog
  • Posts: 9,245
  • Joined: 18-February 07

Re: C++ *

Posted 01 July 2011 - 07:52 AM

arrays are interesting things in C/C++ -- to the compiler an array is a symbol for an address (the address maybe relative (i.e. on the stack) or to some location in the data segement. Now unlike a pointer the compiler does not allocate a location to store this address... it just keeps track of the address, type, and length, just as it does for other variables.

So when you create an integer variable:

int var;

the compiler keeps track of where the variable will be in memory, what its type is, and what size it is.

Well when you declare an array the compiler does the same thing:

char str[20];

the compiler knows where str is in memory, it knows it is of type char[20], and has its size (sizeof(char[20]) == 20 * sizeof(char)).

Now since an array is really just an address the compiler will use the same patterns it uses for pointers to access an array.

so str[10] - is the same as *(str + 10) and since the compiler knows where str is, it can just pop in the address.

So while people often confuse pointers with arrays the two are actually quite different. For one the sizeof(str) == 20*sizeof(char) where as the size of a pointer is the sizeof(char*) which is usually the word size of the computer (i.e. 4 for a 32bit machine). That is, the compile does not use a pointer (a location in memory that holds an address) rather it just knows the address.

arrays can "regress" into a pointer though -- because the compiler knows the address of the array it can always just pop that value into a pointer. And so when you want to pass an array to a function for example you might just pass in a pointer to the array -- the compiler can automatically do this conversion. However some information is lost -- the pointer has no idea how much memory is available for the array. i.e. sizeof(ptr1) == sizeof(ptr2) == sizeof(&anything) -- pointers all have the same size and it is NOT necessarily the size of the array!
Was This Post Helpful? 4
  • +
  • -

#6 E_Geek  Icon User is offline

  • D.I.C Head
  • member icon

Reputation: 45
  • View blog
  • Posts: 236
  • Joined: 20-February 11

Re: C++ *

Posted 01 July 2011 - 08:21 AM

View PostNickDMax, on 01 July 2011 - 07:52 AM, said:

arrays can "regress" into a pointer though -- because the compiler knows the address of the array it can always just pop that value into a pointer. And so when you want to pass an array to a function for example you might just pass in a pointer to the array -- the compiler can automatically do this conversion. However some information is lost -- the pointer has no idea how much memory is available for the array. i.e. sizeof(ptr1) == sizeof(ptr2) == sizeof(&anything) -- pointers all have the same size and it is NOT necessarily the size of the array!


Does this have the potential to cause problems? If so is their a workaround?

And thanks for going into so much detail about this :D
Was This Post Helpful? 0
  • +
  • -

#7 NickDMax  Icon User is offline

  • Can grep dead trees!
  • member icon

Reputation: 2250
  • View blog
  • Posts: 9,245
  • Joined: 18-February 07

Re: C++ *

Posted 01 July 2011 - 09:28 AM

Well, generally it is considered a *feature* rather than a hindered.

However knowing the size of an array is nice. Generally if you allocate a static array you can find its size using something like this:


sizeof(myarray)/sizeof(*myarray)

so for example if I have an int[100] then
sizeof(int[100]) = 100 * sizeof(int)

when you divide that by sizeof(int) you get 100.


However when you allocate a dynamic array (which is just a pointer to some block of memory you requested on the heap) or when you pass an array as a pointer to a function the size is "lost".

So you often need to keep track of your array sizes in some way.

Example: Lets say I want to make a program to find the sum of a bunch of numbers.

One way I could solve the problem is:
#include <iostream>

using namespace std;

int sum(int arr[10]) {
    int s = 0;
    for (int i = 0; i < 10; ++i) {
        s += arr[i];
    }
    return s;
}

int main() {
    int nums[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 100 };
    cout << sum(nums) << endl;
    return 0;
}


This is great... but what if next time I need to get the sum of some different number of items. I might change the program to:
#include <iostream>

using namespace std;

int sum(int arr[], int size) {
    int s = 0;
    for (int i = 0; i < size; ++i) {
        s += arr[i];
    }
    return s;
}

int main() {
    int nums[] = {3, 1, 4, 1, 5, 9, 2, 6, 5, };
    cout << sum(nums, sizeof(nums)/sizeof(*nums)) << endl;
    return 0;
}


but now every time I want to take the sum of a different set of numbers I need to edit the program and recompile... So I might just make myself a neat little utility like this:
#include <iostream>
#include <sstream>

using namespace std;

int sum(int* arr, int size) {
    int s = 0;
    for (int i = 0; i < size; ++i) {
        s += arr[i];
    }
    return s;
}

int main(int argc, char* argv[]) {
    if (argc < 2) {
        cout << "USAGE: sumInts.exe 1 2 3 4 5" << endl;
    }
    int* nums = new int[argc-1];
    int count = 0;
    for (int i = 1; i < argc; ++i) {
        stringstream ss(argv[i]);
        ss >> nums[i-1];
        //cout << nums[i-1] << endl;
        if (!ss) {
            cout << "Non-integer argument ignored: " << argv[i] << endl;
            break;
        }
        count++;
    }
    cout << sum(nums, count) << endl;
    delete[] nums;
    return 0;
}


So by using the pointer I get the most "abstract" and can deal with more general cases. In the last case I have some unknown number of elements that I want to find the sum of. This last version of the function could easily work for for both of the earlier programs!

the first one needs to change the call to:

cout << sum(nums, 10) << endl; -- since we have 10 elements in the array.

the second one does not need a change since we calculate the size of the array already.

So -- the only "problems" caused are that you need to do some book keeping yourself rather than relying upon the compiler to do it for you.
Was This Post Helpful? 4
  • +
  • -

#8 Bench  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 857
  • View blog
  • Posts: 2,343
  • Joined: 20-August 07

Re: C++ *

Posted 02 July 2011 - 02:33 AM

View Postvividexstance, on 01 July 2011 - 02:19 PM, said:

board is an array, an array is basically a pointer to the first element in the array
No, no, NO!

I've lost track of how many times i've seen people spout this non-fact. Its simply not true!

An array IS NOT a pointer!


An array is a contiguous block of memory, a pointer is an address in memory. Just because C and C++ let you cast an array to a pointer does not mean that they are the same.

Please read the FAQs here
http://c-faq.com/aryptr/index.html
Was This Post Helpful? 4
  • +
  • -

#9 vividexstance  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 687
  • View blog
  • Posts: 2,377
  • Joined: 31-December 10

Re: C++ *

Posted 02 July 2011 - 08:12 AM

I said:

Quote

board is an array, an array is basically a pointer to the first element in the array


Here is a quote from Bjarne Stroustrup's "The C++ Programming Language Special Edition" Chapter 5, Section 2.2 page 91:

Quote

In C++, pointers and arrays are closely related. The name of an array can be used as a pointer to its initial element.


That's why I said "basically".
Was This Post Helpful? 0
  • +
  • -

#10 NickDMax  Icon User is offline

  • Can grep dead trees!
  • member icon

Reputation: 2250
  • View blog
  • Posts: 9,245
  • Joined: 18-February 07

Re: C++ *

Posted 02 July 2011 - 08:24 AM

Yes and you were basically right, but there is a lot of confusion caused by that word "basically".

Pointers and arrays ARE closely related, but where as a pointer is a variable with a value of an address. and array variable is just an address (to the compiler it is an address, type, and size).

It has actually taken me a long time to "get" that -- for a long time I made mistakes or was frustrated by attempts to use pointers and arrays interchangeably. There IS a logical difference though and if you don't keep it in mind then these errors can be VERY frustrating because in your mind's construct of the compiler it should work.
Was This Post Helpful? 0
  • +
  • -

#11 vividexstance  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 687
  • View blog
  • Posts: 2,377
  • Joined: 31-December 10

Re: C++ *

Posted 02 July 2011 - 09:05 AM

I understand, I just don't like people Bench, who, other than saying "You're Wrong", don't have anything positive to add. Like you did by explaining the differences between pointers and arrays.

This post has been edited by vividexstance: 02 July 2011 - 09:06 AM

Was This Post Helpful? 0
  • +
  • -

#12 NickDMax  Icon User is offline

  • Can grep dead trees!
  • member icon

Reputation: 2250
  • View blog
  • Posts: 9,245
  • Joined: 18-February 07

Re: C++ *

Posted 02 July 2011 - 09:38 AM

Well, it may have come across as a little rude but member Bench is one of our most respected Experts and has in the past shown great restraint and patiently walked beginners though explanations.

So what I am saying is: If you make a technical misstep (even if YOU Know what is right and didn't MEAN anything misleading) then you can expect to be called on it, and when you are, just grin and apologize (or just let it go). -- This happens to me all the time. I admit sometimes it ruffles my feathers but I try not to take it personally because that does not generally lead anywhere.

And his comment DID contribute to the discussion because it made it VERY clear that arrays and pointer are not "basically the same thing" because really they are not.

On the other hand... if the person who "corrects" you is wrong -- you have my permission to point and laugh as half the other members jump to "correct" them. The forum can be a harsh place for mistakes and know-it-all attitudes.
Was This Post Helpful? 1
  • +
  • -

#13 vividexstance  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 687
  • View blog
  • Posts: 2,377
  • Joined: 31-December 10

Re: C++ *

Posted 02 July 2011 - 10:15 AM

Oh I've found that one out already, thanks though for your response.
Was This Post Helpful? 0
  • +
  • -

#14 Bench  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 857
  • View blog
  • Posts: 2,343
  • Joined: 20-August 07

Re: C++ *

Posted 03 July 2011 - 01:59 AM

View PostNickDMax, on 02 July 2011 - 05:38 PM, said:

Well, it may have come across as a little rude
It did, and I apologise to vividexstance for the tone of the post, although I think the array-is-a-pointer analogy is one of those which ends up being very misleading for a great number of people. Nearly all of us have heard it while learning C, and probably believed it for a while too. To my mind, comparing arrays and pointers ends up being the seed for all kinds of confusion later on.

This post has been edited by Bench: 03 July 2011 - 01:59 AM

Was This Post Helpful? 1
  • +
  • -

Page 1 of 1