Stroustrup 5.9, exercise 3

A

arnuld

i did what i could do at Best to solve this exercise and this i what i
have come up with:

----------- PROGRAMME --------------
/* Stroustrup 5.9, exercise 3

STATEMENT:
Use typedef to define the types:

unsigned char
const unsigned char
pointer to integer
pointer to pointer to char
pointer to array of char
array of 7 pointers to int
pointer to an array of 7 pointers to iint
array of 8 arrays of 7 pointers to int

*/


#include<iostream>

int main()
{
typedef unsigned char Uchar;
typedef const unsigned char CUchar;
typedef int* Pi;
typedef char** PPi;

// to define a type for "pointer to an array of char"
// using typedef
const int arr_size = 10;
char arr[arr_size];
char* pac = &arr;
typedef pac PAchar;

// to define a type for "array of 7 pointers to int"
// using typedef
const int arr_size2 = 7;
typedef int* arr2[arr_size2] Arr7Pint;

// to define a type for
// "a pointer to an array of 7 pointers to int"
// using typedef
int** ppi = arr2;
typedef ppi PPint;

// to define a type for
// "array of 8 arrays of 7 pointers to init"
// using typedef
const int arr_size3= 8;
PPint arr3[arr_size3];

return 0;
}

------------ OUTPUT ----------------
[arch@voodo tc++pl]$ g++ 5.9_ex-03.cpp
5.9_ex-03.cpp: In function 'int main()':
5.9_ex-03.cpp:31: error: cannot convert 'char (*)[10]' to 'char*' in
initialization
5.9_ex-03.cpp:32: error: 'pac' does not name a type
5.9_ex-03.cpp:37: error: expected initializer before 'Arr7Pint'
5.9_ex-03.cpp:42: error: 'arr2' was not declared in this scope
5.9_ex-03.cpp:43: error: 'ppi' does not name a type
5.9_ex-03.cpp:49: error: 'PPint' was not declared in this scope
5.9_ex-03.cpp:49: error: expected `;' before 'arr3'
[arch@voodo tc++pl]$
 
M

Mike Wahler

arnuld said:
i did what i could do at Best to solve this exercise and this i what i
have come up with:

------------ OUTPUT ----------------
[arch@voodo tc++pl]$ g++ 5.9_ex-03.cpp
5.9_ex-03.cpp: In function 'int main()':
5.9_ex-03.cpp:31: error: cannot convert 'char (*)[10]' to 'char*' in
initialization
5.9_ex-03.cpp:32: error: 'pac' does not name a type
5.9_ex-03.cpp:37: error: expected initializer before 'Arr7Pint'
5.9_ex-03.cpp:42: error: 'arr2' was not declared in this scope
5.9_ex-03.cpp:43: error: 'ppi' does not name a type
5.9_ex-03.cpp:49: error: 'PPint' was not declared in this scope
5.9_ex-03.cpp:49: error: expected `;' before 'arr3'
[arch@voodo tc++pl]$

What about these error messages don't you understand?

-Mike
 
A

arnuld

What about these error messages don't you understand?

i have corrected some but was not able to correct all.

------------ PROGRAMME -----------
#include<iostream>

int main()
{
typedef unsigned char Uchar;
typedef const unsigned char CUchar;
typedef int* Pi;
typedef char** PPi;

// to define a type for "pointer to an array of char"
// using typedef
const int arr_size = 10;
char arr[arr_size];
char* pac = arr;
typedef pac PAchar;

// to define a type for "array of 7 pointers to int"
// using typedef
const int arr_size2 = 7;
int* arr2[arr_size2];
typedef int* arr2 Arr7Pint;

// to define a type for
// "a pointer to an array of 7 pointers to int"
// using typedef
int** ppi = arr2;
typedef ppi PPint;

// to define a type for
// "array of 8 arrays of 7 pointers to init"
// using typedef
const int arr_size3= 8;
PPint arr3[arr_size3];

return 0;
}

------------ OUTPUT ------------
[arch@voodo tc++pl]$ g++ 5.9_ex-03.cpp
5.9_ex-03.cpp: In function 'int main()':
5.9_ex-03.cpp:32: error: 'pac' does not name a type
5.9_ex-03.cpp:38: error: expected initializer before 'Arr7Pint'
5.9_ex-03.cpp:44: error: 'ppi' does not name a type
5.9_ex-03.cpp:50: error: 'PPint' was not declared in this scope
5.9_ex-03.cpp:50: error: expected `;' before 'arr3'
[arch@voodo tc++pl]$


#1) 5.9_ex-03.cpp:32: error: 'pac' does not name a type

but i have defined it in: char* pac = arr;


#2) 5.9_ex-03.cpp:38: error: expected initializer before 'Arr7Pint'

"int* arr2" is the initializer in "typedef int* arr2 Arr7Pint;". why
error ?


#3) 5.9_ex-03.cpp:44: error: 'ppi' does not name a type

same as error #1


#4) 5.9_ex-03.cpp:50: error: 'PPint' was not declared in this scope

it is declared in the same scope (scope of "main")


#5) 5.9_ex-03.cpp:50: error: expected `;' before 'arr3'

line 50: PPint arr3[arr_size3];

i did not get it.
 
A

Alf P. Steinbach

* arnuld:
On Mar 30, 10:20 pm, "Mike Wahler" <[email protected]> wrote:
What about these error messages don't you understand?

i have corrected some but was not able to correct all.

------------ PROGRAMME -----------
#include<iostream>

int main()
{
typedef unsigned char Uchar;
typedef const unsigned char CUchar;
typedef int* Pi;
typedef char** PPi;

// to define a type for "pointer to an array of char"
// using typedef
const int arr_size = 10;
char arr[arr_size];
char* pac = arr;
typedef pac PAchar;

'pac' is a variable. A variable is not a type. It cannot be used as a
type.

'arr' is also a variable.

Instead of declaring a variable, consider adding the word 'typedef' to
define a type.

// to define a type for "array of 7 pointers to int"
// using typedef
const int arr_size2 = 7;
int* arr2[arr_size2];
typedef int* arr2 Arr7Pint;

'arr2' is a variable. A variable is not a type. It cannot be used as a
type, and in addition the declaration syntax is incorrect.

Instead of declaring a variable, consider adding the word 'typedef' to
define a type.

// to define a type for
// "a pointer to an array of 7 pointers to int"
// using typedef
int** ppi = arr2;
typedef ppi PPint;

'ppi' is a variable. A variable is not a type. It cannot be used as a
type, and in addition the declaration syntax is incorrect.

Instead of declaring a variable, consider adding the word 'typedef' to
define a type.

// to define a type for
// "array of 8 arrays of 7 pointers to init"
// using typedef
const int arr_size3= 8;
PPint arr3[arr_size3];

Due to errors above, 'PPint' is not a type. It's undefined.

If 'PPint' was a type, then 'arr3' would be a variable. A variable is
not a type. Instead of declaring a variable, consider adding the word
'typedef' to define a type.
 
A

arnuld

* arnuld:
// to define a type for "pointer to an array of char"
// using typedef
const int arr_size = 10;
char arr[arr_size];
char* pac = arr;
typedef pac PAchar;
'pac' is a variable. A variable is not a type. It cannot be used as a
type.

ok, but i can not use typedef here. see this:

typedef char* arr pac;

this gives error: "expected initializer before pac"

i don't understand how to create a "typedef" for "pointer to an array
of char"

:-(
 
A

Alf P. Steinbach

* arnuld:
On Mar 31, 12:53 pm, "Alf P. Steinbach" <[email protected]> wrote:
* arnuld:
// to define a type for "pointer to an array of char"
// using typedef
const int arr_size = 10;
char arr[arr_size];
char* pac = arr;
typedef pac PAchar;
'pac' is a variable. A variable is not a type. It cannot be used as a
type.

ok, but i can not use typedef here. see this:

typedef char* arr pac;

this gives error: "expected initializer before pac"

i don't understand how to create a "typedef" for "pointer to an array
of char"

Explain your thinking when writing

typedef char* arr pac;

What do (or did) you think this should mean?
 
A

Alf P. Steinbach

* arnuld:
i *know* it is wrong. you can think of it like this:

typedef (char* arr) pac;


i just want to create a "typdef" for "char* pac = arr" but i don know
how to go doing that.

Let's take things in order then.


1. Variable.

A /variable/ is a named chunk of memory.


2. Type.

The variable's /type/ tells how the contents (bits) of that chunk of
memory should be interpreted, e.g. as an integer or as a string of
characters. It also tells how large the chunk of memory should be.


3. Declaration.

A /declaration/ of a variable states the variable's type, name and
possibly initial value:

char* pac = arr;
^^^^^ ^^^^ ^^^
type name initial value


4. Typedef.

A /typedef/ defines a name, an extra, additional name, for a type.

typedef int WholeNumber;

defines the new name WholeNumber as an additional name for type 'int'.

What goes into this definition is (1) a type, and (2) a name, the name
being defined:

typedef int WholeNumber;
^^^ ^^^^^^^^^^^
type name being defined

Note: Types can have names, variables can have names, functions can have
names, and so on. That doesn't mean that a variable is a type.

You can not typedef a new name for a variable. To define a new name for
a variable use a reference.

You can not typedef a new name for a declaration. Declarations simply
don't have names.

You can only typedef a new name for a type.

Except for the keyword 'typedef' a typedef has the same form as a
variable declaration. Where the variable's name would go in a variable
declaration, the type's new name goes in a typedef. So:

char* aCharPointer; // A variable which is a pointer to char.
typedef char* CharPointer; // A name for the type 'char*'.

Note here both the similarity, and that the typedef does not refer to
the variable, that the variable declaration was just thrown in for you
to see the similarity.

The typedef stands entirely on its own:

typedef char* CharPointer; // A name for the type 'char*'.

The defined type name can then be used to declare a variable, like

CharPointer aCharPointer;

which has the same effect as the first declaration of 'aCharPointer'.

Another example:

typedef double ThreeDoubles[3]; // A name for the type 'double[3]'.

Now the defined type name can be used to declare a variable, or variables:

ThreeDoubles a;
ThreeDoubles b;

And so on.

Names of types are used to define variables.

Variables are not used to define types.
 
A

arnuld

* arnuld:


Let's take things in order then.

ok :)

1. Variable.

A /variable/ is a named chunk of memory.

i know this.
2. Type.

The variable's /type/ tells how the contents (bits) of that chunk of
memory should be interpreted, e.g. as an integer or as a string of
characters. It also tells how large the chunk of memory should be.

i knew only about the second sentence, not the 1st one.

3. Declaration.
A /declaration/ of a variable states the variable's type, name and
possibly initial value:
char* pac = arr;
^^^^^ ^^^^ ^^^
type name initial value
4. Typedef.

A /typedef/ defines a name, an extra, additional name, for a type.

typedef int WholeNumber;

defines the new name WholeNumber as an additional name for type 'int'.

What goes into this definition is (1) a type, and (2) a name, the name
being defined:

typedef int WholeNumber;
^^^ ^^^^^^^^^^^
type name being defined


i know very well all this.


The typedef stands entirely on its own:

typedef char* CharPointer; // A name for the type 'char*'.

The defined type name can then be used to declare a variable, like

CharPointer aCharPointer;

which has the same effect as the first declaration of 'aCharPointer'.

Another example:

typedef double ThreeDoubles[3]; // A name for the type 'double[3]'.

Now the defined type name can be used to declare a variable, or variables:

ThreeDoubles a;
ThreeDoubles b;

And so on.

Names of types are used to define variables.

Variables are not used to define types.


all of these examples are quite simple and i guess they don't tell
anything indirectly/directly about how to create a typedef for "as
array of 7 pointers to strings"

you are talking about simplicity (simple definitions of things) BUT
Stroustrup (in exercises) is talking about complexity & complexity.
 
A

Alf P. Steinbach

* arnuld:
Another example:

typedef double ThreeDoubles[3]; // A name for the type 'double[3]'.

Now the defined type name can be used to declare a variable, or variables:

ThreeDoubles a;
ThreeDoubles b;

And so on.

Names of types are used to define variables.

Variables are not used to define types.


all of these examples are quite simple and i guess they don't tell
anything indirectly/directly about how to create a typedef for "as
array of 7 pointers to strings"

you are talking about simplicity (simple definitions of things) BUT
Stroustrup (in exercises) is talking about complexity & complexity.

Well it's difficult to guide you further without just telling you what
to write, something you could copy and paste, which would be no good.

But consider, above you have an example of typedef'ing an array of 3
doubles.

It could have been an array 3 pointers to strings.

Or 7 pointers to strings.

All you need is a name for the type "pointer to string", to use instead
of the name "double", and there's been at least one concrete example in
this thread of how to typedef a name for "pointer to string".
 
A

arnuld

Well it's difficult to guide you further without just telling you what
to write, something you could copy and paste, which would be no good.

i know and i don't want anybody to do so.

But consider, above you have an example of typedef'ing an array of 3
doubles.

this is your example:

typedef double ThreeDoubles[3]; // A name for the type 'double[3]'.

ThreeDoubles a;
ThreeDoubles b;

i don't get it your "information in comment" here. you say it is of
type "double[3]" but i think it is of type "double". compare it with
what you said earlier:


typedef int WholeNumber;
^^^ ^^^^^^^^^^^
type name being defined


typedef double ThreeDoubles[3];


ThreeDouble[3] = name being defined
double = type

so you declarations must be like this:

ThreeDoubles[3] a;
ThreeDoubles[3] b;

because "ThreeDoubles[3]" (NOT ThreeDouble )is just a typedef
(synonym) from "double"

It could have been an array 3 pointers to strings.
Or 7 pointers to strings.
All you need is a name for the type "pointer to string", to use instead
of the name "double", and there's been at least one concrete example in
this thread of how to typedef a name for "pointer to string".

typedef std::string Pstr*;
 
A

Alf P. Steinbach

* arnuld -> Alf:
this is your example:

typedef double ThreeDoubles[3]; // A name for the type 'double[3]'.

ThreeDoubles a;
ThreeDoubles b;

i don't get it your "information in comment" here. you say it is of
type "double[3]" but i think it is of type "double".
Nope.


compare it with what you said earlier:


typedef int WholeNumber;
^^^ ^^^^^^^^^^^
type name being defined
Yes.


typedef double ThreeDoubles[3];


ThreeDouble[3] = name being defined
double = type

Nope.

typedef double ThreeDoubles[3];
^^^^^^ ^^^
t y p e


typedef double ThreeDoubles[3];
^^^^^^^^^^^^
n a m e

It seems you have assumed a strict order (this first, then that) or
substitutability (if this name stands for expression x then I can
replace this name with x), neither of which hold for C and C++ declarations.

The syntax for declarations is a collection of special cases.

To reduce them to more simple things, use typedef liberally.

Build up types in simple, small naming steps.

so you declarations must be like this:

ThreeDoubles[3] a;
ThreeDoubles[3] b;

No, that's a different programming language (or languages).
 
A

arnuld

arnuld wrote:
typedef double ThreeDoubles[3];
^^^^^^ ^^^
t y p e

typedef double ThreeDoubles[3];
^^^^^^^^^^^^
n a m e
It seems you have assumed a strict order (this first, then that) or
substitutability (if this name stands for expression x then I can
replace this name with x), neither of which hold for C and C++ declarations.

i understood "substitutability" is synonym for typedef. i was wrong, i
think C and C++ declarations are much more deeper than that and
Stroustrup did not explain that (but K&R2 does explain that, i checked
that).

anyway, i tried these and they compile with any error:


// to define a type for "pointer to an array of 7 chars"
typedef char *PAchar[7];

// typedef for an array of 7 pointers to integers
typedef int* APint[7];

// typedef for "pointer to an array of 7 pointers to integers
typedef int* *PAPint[7];


are they right or wrong ?
ThreeDoubles[3] a;
ThreeDoubles[3] b;
No, that's a different programming language (or languages).

:-(
 
A

arnuld

Finally, how about this one:

// typedef for "an array of 8 arrays of 7 pointers to int"
typedef int* AAPint[8][7];


it compiles successfully. is it right ?

BTW, i learnt this from K&R2
 
A

Alf P. Steinbach

* arnuld:
arnuld wrote:
typedef double ThreeDoubles[3];
^^^^^^ ^^^
t y p e

typedef double ThreeDoubles[3];
^^^^^^^^^^^^
n a m e
It seems you have assumed a strict order (this first, then that) or
substitutability (if this name stands for expression x then I can
replace this name with x), neither of which hold for C and C++ declarations.

i understood "substitutability" is synonym for typedef. i was wrong, i
think C and C++ declarations are much more deeper than that and
Stroustrup did not explain that (but K&R2 does explain that, i checked
that).

anyway, i tried these and they compile with any error:


// to define a type for "pointer to an array of 7 chars"
typedef char *PAchar[7];

// typedef for an array of 7 pointers to integers
typedef int* APint[7];

// typedef for "pointer to an array of 7 pointers to integers
typedef int* *PAPint[7];


are they right or wrong ?

They are syntactically valid. But the first two are of identical form,
yet the comments say they should denote types of very different form.
Hence one of them, or one of the comments, must be incorrect.

How can you test?

You can declare a variable of the type,

PAchar testPA;

and if the PAchar type is a pointer to ..., then you should be able to
initialize it with ...,

char arrayOf7Chars[7];
PAchar testPA = arrayOf7Chars;

If that works then the PAchar type is OK.

Similarly, if APint is an array of 7 pointers, then you should be able
to initialize a variable of that type with 7 nullpointers,

APInt testAP = {0, 0, 0, 0, 0, 0, 0};

No matter which one turns out to be incorrect it then needs to be corrected.

One way is to use a parenthesis to override the operator precedence, in
the same way as e.g. 2+3*4 and (2+3)*4 means different things.

Another way is as mentioned to use typedefs to build up types by small
naming steps. That means instead of one big typedef use two or more,
and not having more than one operator in each typedef. That way you
avoid dealing with operator precedence.
 
A

arnuld

They are syntactically valid. But the first two are of identical form,
yet the comments say they should denote types of very different form.
Hence one of them, or one of the comments, must be incorrect.

How can you test?

You can declare a variable of the type,

PAchar testPA;

and if the PAchar type is a pointer to ..., then you should be able to
initialize it with ...,

char arrayOf7Chars[7];
PAchar testPA = arrayOf7Chars;

If that works then the PAchar type is OK.


i checked it, it is wrong. this gives compile-time error:

char arr[7];
PAchar testPAchar = arr;

Similarly, if APint is an array of 7 pointers, then you should be able
to initialize a variable of that type with 7 nullpointers,

APInt testAP = {0, 0, 0, 0, 0, 0, 0};

No matter which one turns out to be incorrect it then needs to be corrected.


APint is correct. see:

int my = 800;
int* myP = &my;
APint testAPint = {0,0,0,0,0,0,myP};

std::cout << "testAPint[6] = " << *testAPint[6] << std::endl;


it prints 800 on the terminal, correct.
One way is to use a parenthesis to override the operator precedence, in
the same way as e.g. 2+3*4 and (2+3)*4 means different things.

so, is it correct:

typedef (int*) APint[7];

Another way is as mentioned to use typedefs to build up types by small
naming steps. That means instead of one big typedef use two or more,
and not having more than one operator in each typedef. That way you
avoid dealing with operator precedence.

can you provide an example ?
 
A

Alf P. Steinbach

* arnuld:
On Apr 1, 3:16 pm, "Alf P. Steinbach" <[email protected]> wrote:
They are syntactically valid. But the first two are of identical form,
yet the comments say they should denote types of very different form.
Hence one of them, or one of the comments, must be incorrect.

How can you test?

You can declare a variable of the type,

PAchar testPA;

and if the PAchar type is a pointer to ..., then you should be able to
initialize it with ...,

char arrayOf7Chars[7];
PAchar testPA = arrayOf7Chars;

If that works then the PAchar type is OK.


i checked it, it is wrong. this gives compile-time error:

char arr[7];
PAchar testPAchar = arr;

Well, I forgot an "&" in there.

But yes, it should still give a compile time error when that is added,

char arr[7];
PAchar testPAchar = &arr; // Should not compile.


[snip]
can you provide an example ?

Instead of

// typedef for an array of 7 pointers to integers
typedef int* APint[7];

write

typedef int* IntPtr;
typedef IntPtr ArrayOfSevenIntPtr[7];
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,770
Messages
2,569,583
Members
45,073
Latest member
DarinCeden

Latest Threads

Top