Stroustrup 5.9, exercise 7

A

arnuld

/* Stroustrup: 5.9 exercise 7

STATEMENTS:
Define a table of the name sof months o fyear and the number of days
in each month. write out that table. Do this twice:

1.) using ar array of char for names of months and an array of numbers
for number of days.

2.) using an array of structures. each structure holds the name of the
month
and its corresponding number of days.


for now, i have tried the (1) only.
*/


#include<iostream>

int main()
{
const int months = 12;
int i = 0;

const char* ArrOfMonths[] = { "JAN", "FEB", "MAR", "APR", "MAY",
"JUN",
"JUL", "AUG", "SEP", "OCT", "NOV", "DEC" };

const int ArrOfDays[] = {31, 28, 31, 30, 31,30, 31, 31, 30, 31, 30,
31};

std::cout << "\tMONTH\tDAYS\n";

const char** pmonths = ArrOfMonths;
const int* pdays = ArrOfDays[0];

for(int i = 0; *pmonths != '\0' || *pdays != '\0'; ++i)
{
std::cout << "\t" << *pmonths
<< "\t" << *pdays
<< std::endl;
++pmonths;
++pdays;
}


return 0;
}
----------------- OUTPUT -----------------
[arch@voodo tc++pl]$ g++ 5.9_ex-07.cpp
5.9_ex-07.cpp: In function 'int main()':
5.9_ex-07.cpp:31: error: invalid conversion from 'const int' to 'const
int*'
[arch@voodo tc++pl]$
 
J

Jacek Dziedzic

arnuld said:
/* Stroustrup: 5.9 exercise 7

STATEMENTS:
Define a table of the name sof months o fyear and the number of days
in each month. write out that table. Do this twice:

1.) using ar array of char for names of months and an array of numbers
for number of days.

2.) using an array of structures. each structure holds the name of the
month
and its corresponding number of days.


for now, i have tried the (1) only.
*/


#include<iostream>

int main()
{
const int months = 12;
int i = 0;

const char* ArrOfMonths[] = { "JAN", "FEB", "MAR", "APR", "MAY",
"JUN",
"JUL", "AUG", "SEP", "OCT", "NOV", "DEC" };

const int ArrOfDays[] = {31, 28, 31, 30, 31,30, 31, 31, 30, 31, 30,
31};

std::cout << "\tMONTH\tDAYS\n";

const char** pmonths = ArrOfMonths;
const int* pdays = ArrOfDays[0];

for(int i = 0; *pmonths != '\0' || *pdays != '\0'; ++i)
{
std::cout << "\t" << *pmonths
<< "\t" << *pdays
<< std::endl;
++pmonths;
++pdays;
}


return 0;
}
----------------- OUTPUT -----------------
[arch@voodo tc++pl]$ g++ 5.9_ex-07.cpp
5.9_ex-07.cpp: In function 'int main()':
5.9_ex-07.cpp:31: error: invalid conversion from 'const int' to 'const
int*'
[arch@voodo tc++pl]$

Here:
const int* pdays = ArrOfDays[0];
you are trying to assign ArrOfDays[0], which is a
const int to a const int* and the compiler tells
you exactly that.

HTH,
- J.
 
A

arnuld

Here:
const int* pdays = ArrOfDays[0];
you are trying to assign ArrOfDays[0], which is a
const int to a const int* and the compiler tells
you exactly that.

yes, a pointer is always "int*". i am trying to create a pointer to
the 1st element of an Array of Integers. so it needs to be "int*".
since integers(elements of the array) are "const" so declared a
"pointer to a const".

i am not trying to convert anything, just want to declare a "pointer"
to the 1st element of an array.
 
A

arnuld

Here:
const int* pdays = ArrOfDays[0];
you are trying to assign ArrOfDays[0], which is a
const int to a const int* and the compiler tells
you exactly that.

ok, here is the corrected code. it took me 6 hours to correct it and
it runs and it does what i want but it also produces some *additional*
output. notice the last lines of output:

---------- PROGRAMME -------------
/* Stroustrup: 5.9 exercise 7

STATEMENTS:
Define a table of the name sof months o fyear and the number of days
in each month. write out that table. Do this twice:

1.) using ar array of char for names of months and an array of numbers
for number of days.

2.) using an array of structures. each structure holds the name of the
month
and its corresponding number of days.

*/


#include<iostream>

int main()
{
char* ArrOfMonths[] = { "JAN", "FEB", "MAR", "APR", "MAY", "JUN",
"JUL", "AUG", "SEP", "OCT", "NOV", "DEC" };

const int ArrOfDays[] = {31, 28, 31, 30, 31,30, 31, 31, 30, 31, 30,
31};

std::cout << "\tMONTH\tDAYS\n";

char** pmonths = ArrOfMonths;
const int* pdays = &ArrOfDays[0];

for(int i = 0; *pmonths != '\0' || *pdays != '\0'; ++i)
{
std::cout << "\t" << *pmonths
<< "\t" << *pdays
<< std::endl;
++pmonths;
++pdays;
}


return 0;
}
--------- OUTPUT -----------
[arch@voodo tc++pl]$ g++ -ansi -pedantic -Wall -Wextra 5.9_ex-07.cpp
[arch@voodo tc++pl]$ ./a.out
MONTH DAYS
JAN 31
FEB 28
MAR 31
APR 30
MAY 31
JUN 30
JUL 31
AUG 31
SEP 30
OCT 31
NOV 30
DEC 31
l.???
5128522
FEB 4343110
Segmentation fault
[arch@voodo tc++pl]$
 
A

arnuld

...[SNIP]...
AUG 31
SEP 30
OCT 31
NOV 30
DEC 31
l.?? ?
5128522
FEB 4343110
Segmentation fault
[arch@voodo tc++pl]$

ok, i got it. the arrays do not have a '\0' character i the end as i
used "{}" to create them. only string literals have '\0' in the end.
so the pointers went beyond the array comparing whatever was beyond
the array. now i used the array size (== 12) to control the "for" loop
and it does exactly what it was intended to.


Hmmm.. at least after 6-8 hours i was able to solve the half of the
exercise and now i will get down to the remaining part.
 
A

arnuld

ok, i got it. the arrays do not have a '\0' character i the end as i
used "{}" to create them. only string literals have '\0' in the end.
so the pointers went beyond the array comparing whatever was beyond
the array. now i used the array size (== 12) to control the "for" loop
and it does exactly what it was intended to.

Hmmm.. at least after 6-8 hours i was able to solve the half of the
exercise and now i will get down to the remaining part.


sorry forgot to post code:

----------- PROGRAMME -------
/* Stroustrup: 5.9 exercise 7

STATEMENTS:
Define a table of the name sof months o fyear and the number of days
in each month. write out that table. Do this twice:

1.) using ar array of char for names of months and an array of numbers
for number of days.

2.) using an array of structures. each structure holds the name of the
month
and its corresponding number of days.

*/


#include<iostream>

int main()
{
const int months = 12;
char* ArrOfMonths[] = { "JAN", "FEB", "MAR", "APR", "MAY", "JUN",
"JUL", "AUG", "SEP", "OCT", "NOV", "DEC" };

//an array of constant integers
const int ArrOfDays[] = {31, 28, 31, 30, 31,30, 31, 31, 30, 31, 30,
31};


std::cout << "\tMONTH\tDAYS\n";

char** pmonths = ArrOfMonths;
const int* pdays = &ArrOfDays[0]; // pointer to the constant integer

for(int i = 0; i < months; ++i)
{
std::cout << "\t" << *pmonths
<< "\t" << *pdays
<< std::endl;
++pmonths;
++pdays;
}


return 0;
}

---------- OUTPUT ------------
[arch@voodo tc++pl]$ g++ -ansi -pedantic -Wall -Wextra 5.9_ex-07.cpp
[arch@voodo tc++pl]$ ./a.out
MONTH DAYS
JAN 31
FEB 28
MAR 31
APR 30
MAY 31
JUN 30
JUL 31
AUG 31
SEP 30
OCT 31
NOV 30
DEC 31
[arch@voodo tc++pl]$
 
A

Alf P. Steinbach

* arnuld:
On Apr 1, 9:09 pm, Jacek Dziedzic <[email protected]> >
Here:
const int* pdays = ArrOfDays[0];
you are trying to assign ArrOfDays[0], which is a
const int to a const int* and the compiler tells
you exactly that.

ok, here is the corrected code. it took me 6 hours to correct it

You're not a quitter, that's for sure.

and
it runs and it does what i want but it also produces some *additional*
output. notice the last lines of output:

---------- PROGRAMME -------------
/* Stroustrup: 5.9 exercise 7

STATEMENTS:
Define a table of the name sof months o fyear and the number of days
in each month. write out that table. Do this twice:

1.) using ar array of char for names of months and an array of numbers
for number of days.

2.) using an array of structures. each structure holds the name of the
month
and its corresponding number of days.

*/


#include<iostream>

int main()
{
char* ArrOfMonths[] = { "JAN", "FEB", "MAR", "APR", "MAY", "JUN",
"JUL", "AUG", "SEP", "OCT", "NOV", "DEC" };

const int ArrOfDays[] = {31, 28, 31, 30, 31,30, 31, 31, 30, 31, 30,
31};

std::cout << "\tMONTH\tDAYS\n";

char** pmonths = ArrOfMonths;
const int* pdays = &ArrOfDays[0];

for(int i = 0; *pmonths != '\0' || *pdays != '\0'; ++i)

Make that condition simply

i < 12

You don't have zero-terminated arrays.

Thus with the current condition the loop only stops when it causes an
operating system level exception, or coincidentally the condition
becomes true for some arbitrary memory content somewhere.

Other nits, a.k.a. possible improvements: (1) ArrOfMonths could and
probably should be declared as

char const* const ArrOfMonths[] = ...

since it's all very constant, and (2) instead of using pointers in the
loop, you could and probably should just use array indexing, x.

Hth.,

- Alf
 
A

arnuld

You're not a quitter, that's for sure.
:)


Make that condition simply

i < 12

yep, before reading your reply, i just used:

const int month = 12;

to avoid any magic numbers in code.

You don't have zero-terminated arrays.

Thus with the current condition the loop only stops when it causes an
operating system level exception, or coincidentally the condition
becomes true for some arbitrary memory content somewhere.


yes, i knew that. it seems like either you did not read my next reply
or you are a kind man :)

Other nits, a.k.a. possible improvements: (1) ArrOfMonths could and
probably should be declared as

char const* const ArrOfMonths[] = ...


this one i don't know. does it mean:

"a constant pointer to a constant char"

if it means this then i culd have declared it like this:

const char *const ArrOfMonths[] = ....

is it right ?
since it's all very constant, and (2) instead of using pointers in the
loop, you could and probably should just use array indexing, x.


yes, i could but i did not because that way, to me, an array look like
a vector and it confuses my thinking-level. "pointers" keep my
thinking on "array-level" and "indexing" keeps me thinking about
"vectors".

yep, it did :)
 
S

Sarath

You're not a quitter, that's for sure.
:)

Make that condition simply

yep, before reading your reply, i just used:

const int month = 12;

to avoid any magic numbers in code.
You don't have zero-terminated arrays.
Thus with the current condition the loop only stops when it causes an
operating system level exception, or coincidentally the condition
becomes true for some arbitrary memory content somewhere.

yes, i knew that. it seems like either you did not read my next reply
or you are a kind man :)
Other nits, a.k.a. possible improvements: (1) ArrOfMonths could and
probably should be declared as
char const* const ArrOfMonths[] = ...

this one i don't know. does it mean:

"a constant pointer to a constant char"

if it means this then i culd have declared it like this:

const char *const ArrOfMonths[] = ....

is it right ?
since it's all very constant, and (2) instead of using pointers in the
loop, you could and probably should just use array indexing, x.


yes, i could but i did not because that way, to me, an array look like
a vector and it confuses my thinking-level. "pointers" keep my
thinking on "array-level" and "indexing" keeps me thinking about
"vectors".

yep, it did :)


Hi Arnuld I've two suggestions(practices)

1. const int* pdays = &ArrOfDays[0]; and const int* pdays = ArrOfDays;
are not having any difference but still the latter representation is
more meaningful as you are represeting a whole array. The first style
of representation will be meaningful when you are iterating from a
radomly selected index.

2. It's better to use strict size for arrays as it not supposed to
modify
const char* ArrOfMonths[months] declaration will ensure that you are
having exactly 12 elements in the array. same case for
ArrOfDays[months]. This is not apppropariate in all cases but in this
cases (or such cases)

Hope you get what I meant.

Regards,
Sarath - http://sarathc.wordpress.com/
 
A

arnuld

Hi Arnuld I've two suggestions(practices)

1. const int* pdays = &ArrOfDays[0]; and const int* pdays = ArrOfDays;
are not having any difference but still the latter representation is
more meaningful as you are represeting a whole array. The first style
of representation will be meaningful when you are iterating from a
radomly selected index.

i think "ArrOfdays" will be simply and implicitly converted to
"&ArrOfDays[0]" where as the latter shows that you are only pointing
to the 1st element of the array, the true part of "pointers and
arrays", hence i find it meaningful.
2. It's better to use strict size for arrays as it not supposed to
modify
const char* ArrOfMonths[months] declaration will ensure that you are
having exactly 12 elements in the array. same case for
ArrOfDays[months]. This is not apppropariate in all cases but in this
cases (or such cases)

that i will use, for sure.
 
J

James Kanze

Hi Arnuld I've two suggestions(practices)
1. const int* pdays = &ArrOfDays[0]; and const int* pdays = ArrOfDays;
are not having any difference but still the latter representation is
more meaningful as you are represeting a whole array. The first style
of representation will be meaningful when you are iterating from a
radomly selected index.
i think "ArrOfdays" will be simply and implicitly converted to
"&ArrOfDays[0]" where as the latter shows that you are only pointing
to the 1st element of the array, the true part of "pointers and
arrays", hence i find it meaningful.

I think her point is that at the language level, C++ does not
make a distinction between a pointer to the first element of an
array, and a pointer to a single object (which might be the
first element of an array, or might not be). Such a distinction
is useful for the reader, however; you don't manipulate the
resulting pointers in the same way. Thus, the convention:
&arrOfDays[0] for the address of a single object (which just
happens to be the first element of an array), and simply
arrOfDays for the address of the first element of an array (used
as a substitute for the actual array).
 

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,968
Messages
2,570,150
Members
46,697
Latest member
AugustNabo

Latest Threads

Top