Stroustrup 5.9, exercise 10

A

arnuld

this works fine, any advice for improvement:

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

STATAMENT:
define an array of strings,where strings contains the names months
.. Print those strings. Pass the array to a function that prints those
strings.


SOLUTION:

1.) 1st, i will print array int he "main" using "for" loop
and array indexing.

2.) then i wil print he array using a function and passing the array
to the function as argument(pass by reference).

NOTICE: this post contains only implementation of (1)
*/

#include<iostream>

void print_arr(const char**, size_t);

int main()
{
const char* arr[] = {"january", "february", "march", "april", "may",
"june",
"july", "august", "september", "october", "november",
"december"};


const size_t arr_size = sizeof(arr) / sizeof(*arr);

for(unsigned int i=0; i < arr_size; ++i)
std::cout << '\t' << arr << std::endl;

return 0;
}

------------ OUTPUT --------------------------
[arch@voodo tc++pl]$ g++ -ansi -pedantic -Wall -Wextra test.cpp
[arch@voodo tc++pl]$ ./a.out
january
february
march
april
may
june
july
august
september
october
november
december
[arch@voodo tc++pl]$
 
A

Alf P. Steinbach

* arnuld:
this works fine, any advice for improvement:

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

STATAMENT:
define an array of strings,where strings contains the names months
. Print those strings. Pass the array to a function that prints those
strings.


SOLUTION:

1.) 1st, i will print array int he "main" using "for" loop
and array indexing.

2.) then i wil print he array using a function and passing the array
to the function as argument(pass by reference).

NOTICE: this post contains only implementation of (1)
*/

#include<iostream>

void print_arr(const char**, size_t);

int main()
{
const char* arr[] = {"january", "february", "march", "april", "may",
"june",
"july", "august", "september", "october", "november",
"december"};


const size_t arr_size = sizeof(arr) / sizeof(*arr);

for(unsigned int i=0; i < arr_size; ++i)
std::cout << '\t' << arr << std::endl;

return 0;
}


This looks good. I'd add an extra 'const', "const char* const arr[]",
but that's it. Some people may comment on the use of 'unsigned' for the
loop variable, because 'unsigned' can become problematic for a loop that
counts down; however, with e.g. std::vector there are good reasons to
use std::size_t for the loop variable, and that's an unsigned type too.

------------ OUTPUT --------------------------
[arch@voodo tc++pl]$ g++ -ansi -pedantic -Wall -Wextra test.cpp

This also looks mainly good. Improvement: in order to get warnings
about some (real nasty) problems you need to add the "-O" (optimize)
option, or some other optimization. The only further problem is that I
seem to remember that the g++ folks have deprecated -Wall, and
introduced some other option or set of options. However, I use -Wall
myself. But then, I also use "-o" (out file) with Visual C++, which is
an undocumented option. So perhaps I'm not the best example to follow.
 
A

arnuld

This looks good. I'd add an extra 'const', "const char* const arr[]",
but that's it.

const char* const arr[];

says:

"elements of the array can not be modified and array itself can not"

IIRC, you can not modify an array at all. so i think we do not need
the extra "const".

right ?
Some people may comment on the use of 'unsigned' for the
loop variable, because 'unsigned' can become problematic for a loop that
counts down; however, with e.g. std::vector there are good reasons to
use std::size_t for the loop variable, and that's an unsigned type too.

yes, otherwise, i get a warning saying something like: matching of an
unsigned type with a signed type.

This also looks mainly good. Improvement: in order to get warnings
about some (real nasty) problems you need to add the "-O" (optimize)
option, or some other optimization.

this i what gcc says about "-0":

------------
With -O, the compiler tries to reduce code size and execution time,
without performing any optimizations that
take a great deal of compilation time.

-O turns on the following optimization flags: -fdefer-pop -
fdelayed-branch -fguess-branch-probability
-fcprop-registers -floop-optimize -fif-conversion -fif-
conversion2 -ftree-ccp -ftree-dce -ftree-domina-
tor-opts -ftree-dse -ftree-ter -ftree-lrs -ftree-sra -ftree-
copyrename -ftree-fre -ftree-ch -funit-at-a-time
-fmerge-constants

-O also turns on -fomit-frame-pointer on machines where
doing so does not interfere with debugging.
-----------------
The only further problem is that I
seem to remember that the g++ folks have deprecated -Wall, and
introduced some other option or set of options.

NO, i just checked the manual, it isn't deprecated, 4.1.2 is the
latest version and i use it on my "Arch Voodo".

However, I use -Wall
myself. But then, I also use "-o" (out file) with Visual C++, which is
an undocumented option. So perhaps I'm not the best example to follow.

my friends has VC++ which does not even recognise
"#include<iostream>". it always demands a ".h" in the end. don't know
which version he is using
 
A

Alf P. Steinbach

* arnuld:
On Apr 2, 12:43 pm, "Alf P. Steinbach" <[email protected]> wrote:
This looks good. I'd add an extra 'const', "const char* const arr[]",
but that's it.

const char* const arr[];

says:

"elements of the array can not be modified and array itself can not"

IIRC, you can not modify an array at all. so i think we do not need
the extra "const".

right ?

'const' is never technically /needed/. It's just good programming
practice to apply 'const' wherever possible. Because that way the
chance of inadvertently changing something that shouldn't be changed, is
minimized.
 
A

ajk

'const' is never technically /needed/. It's just good programming
practice to apply 'const' wherever possible. Because that way the
chance of inadvertently changing something that shouldn't be changed, is
minimized.

not to forget: it also provides information for the next programmer
 
J

James Kanze

This looks good. I'd add an extra 'const', "const char* const arr[]",
but that's it.
const char* const arr[];

"elements of the array can not be modified and array itself can not"

Not quite. The array contains pointers. The first const says
that what these pointers point to cannot be modified. (Sort of.
More exactly, it says that it cannot be modified through this
pointer without an explicit cast.) The second const says that
the pointer itself cannot be modified, to point to something
else.

Formally, an array is never const. But it's elements can be
const, which comes out to pretty much the same thing.
IIRC, you can not modify an array at all.

What makes you think that? You cannot modify the topology of
the array (dimensions, etc.), but you can certainly modify the
contents. Like Alf, I use both const in this sort of
expression, to ensure that nothing gets modified.
so i think we do not need the extra "const".

You never need it (except on reference arguments, if you want to
pass temporaries to them). On the other hand, it offers a fair
degree of protection, and very good documentation. I'd use it.
yes, otherwise, i get a warning saying something like: matching of an
unsigned type with a signed type.

Well, it's just a warning:). But it is there for a reason.
Mixed signedness can sometimes have some very strange results.

As a general rule, of course, unless there is some reason for
doing otherwise (and interfacing with an externally imposed
interface which uses unsigned types is a good reason), stick
with int.
this i what gcc says about "-0":

I think that Alf's point was that certain types of errors are
only detectable if the compiler does some flow analysis, and
that g++ (and most other compilers) only do flow analysis if
optimization is turned on.

It's an interesting point of view. Because optimizers are less
robust than normal code generators, I avoid optimization in
production code unless I need it. On the other hand, Alf is
right that there are a number of potential errors (e.g. using an
uninitialized variable) which a compiler can only find if it
does some optimization. So I guess the rule should be to use
optimization in debug builds, but to turn it off in production
builds.

[...]
my friends has VC++ which does not even recognise
"#include<iostream>". it always demands a ".h" in the end. don't know
which version he is using

It must be a very old one; I think <iostream> was already
present in VC++ 5.0, and it was certainly present in 6.0 (which
is what, 10 years old now?).

Note that VC++ was one of the few compilers which handled the
transition gracefully, and offered two different
implementations. Maybe the reason your friends don't use
<iostream> is that some of there code counts on the behavior of
the classical iostream, and either doesn't compile or has the
wrong behavior if they include <iostream>.
 

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

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,066
Latest member
VytoKetoReviews

Latest Threads

Top