473,956 Members | 2,717 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

A CT&P excursion - beat it up!

After completing KNK2, my interest in C was reignited, prompting a
re-reading of Traister's dubious book on pointers. Then I dusted off
the fine ``C Traps and Pitfalls'' by Andy Koenig. Nowadays I primarily
work in PHP, Perl and C++. Consequently my C skills have atrophied.

So inspired by CT&P's ``calendar'' example on page 30, I decided to
brush up on some elementary C (although Koenig describes it as walking
``out on the ice'') with the little toy exercise below.

For posting, here I yanked all the comments for brevity. There's a
(too?) liberal use of typedef, pointers for the sake of pointers and
some blatantly obvious asserts. It compiles cleanly with Sun C 5.8
2005/10/13 on a SPARC and lint shows only functions returning values
that are ignored. The output meets expectations for a non-leap year.

So look this over being brutal and merciless with your critique as I
try to rebuild my flabby C muscles:

#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

enum { MONTHS = 12, DAYS = 31 };
enum { JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV, DEC };
static const char *const months[] = { "JAN", "FEB", "MAR", "APR",
"MAY", "JUN", "JUL", "AUG",
"SEP", "OCT", "NOV", "DEC", };

int main(void)
{
typedef int month_type[DAYS];
typedef month_type *month_ptr_type ;
typedef int *day_ptr_type;

int calendar[MONTHS][DAYS];
month_ptr_type month_ptr;
size_t num_months;
size_t num_days_per_mo nth;

memset(calendar , 0, sizeof calendar);
assert(calendar[DEC][DAYS - 1] == 0);

month_ptr = calendar;
assert(sizeof *month_ptr == DAYS * sizeof(int));

num_months = sizeof calendar / sizeof *calendar;
assert(num_mont hs == MONTHS);

num_days_per_mo nth = sizeof *calendar / sizeof **calendar;
assert(num_days _per_month == DAYS);

for(; month_ptr < calendar + num_months; ++month_ptr) {
day_ptr_type day_ptr = *month_ptr;
int month_num = (month_ptr - calendar + num_months) - num_months;
int days_in_month;
int day_num;

switch(month_nu m) {
case FEB:
days_in_month = 28;
break;
case APR:
case JUN:
case SEP:
case NOV:
days_in_month = 30;
break;
default:
days_in_month = 31;
break;
}

for(day_num = 1; day_num <= days_in_month; ++day_num, ++day_ptr)
*day_ptr = day_num;
}

for(month_ptr = calendar; month_ptr < calendar + num_months; ++month_ptr) {
int month_num = (month_ptr - calendar + num_months) - num_months;
int total_days_in_m onth = -1;
day_ptr_type day_ptr;

for(day_ptr = *month_ptr + num_days_per_mo nth - 1;
day_ptr *month_ptr; --day_ptr) {
if(*day_ptr) {
total_days_in_m onth = *day_ptr;
break;
}
}

printf("month %d (%s) has %d days\n",
month_num + 1, months[month_num], total_days_in_m onth);
}

return EXIT_SUCCESS;
}

Jun 27 '08 #1
29 2094
On Sat, 07 Jun 2008 02:08:07 -0500, Bob Nelson wrote:

[code elided]
0 warnings, 0 errors.

On my machine the output doesn't last long enough to read. Add a getchar()
call somewhere:
>
printf("month %d (%s) has %d days\n",
month_num + 1, months[month_num], total_days_in_m onth);
getchar();
}

return EXIT_SUCCESS;
}
I had to write a perpetual calender for my scientific programming class in
fortran in college. Output was un-fun.
--
The chief value of money lies in the fact that one lives in a world in
which it is overestimated.
H. L. Mencken
Jun 27 '08 #2
Ron Ford said:
On Sat, 07 Jun 2008 02:08:07 -0500, Bob Nelson wrote:

[code elided]
0 warnings, 0 errors.

On my machine the output doesn't last long enough to read. Add a
getchar() call somewhere:
Why should he do that? Learn how to drive a command shell.

--
Richard Heathfield <http://www.cpax.org.uk >
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Jun 27 '08 #3
Ron Ford <ro*@nowhere.ne twrites:
On Sat, 07 Jun 2008 02:08:07 -0500, Bob Nelson wrote:
[code elided]
0 warnings, 0 errors.

On my machine the output doesn't last long enough to read. Add a getchar()
call somewhere:
>>
printf("month %d (%s) has %d days\n",
month_num + 1, months[month_num], total_days_in_m onth);

getchar();
> }

return EXIT_SUCCESS;
}
Don't bother. Just run the program in a way that doesn't cause the
window to close when the program terminates. Not all systems are
Windows; on a non-Windows system, a program that gratuitously waits
for input before terminating would be quite annoying.

--
Keith Thompson (The_Other_Keit h) ks***@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Jun 27 '08 #4
On Sat, 07 Jun 2008 08:42:01 +0000, Richard Heathfield wrote:
Ron Ford said:
>On Sat, 07 Jun 2008 02:08:07 -0500, Bob Nelson wrote:

[code elided]
0 warnings, 0 errors.

On my machine the output doesn't last long enough to read. Add a
getchar() call somewhere:

Why should he do that? Learn how to drive a command shell.
I use Dev-Cpp for quick and dirty C stuff and simply could not find a
means, from within the IDE, to pause a program before windows eats it up.
I ended up putting in a dos-shortcut where the executable lives, and that
works, but it misses the whole point of staying within an IDE during
development and testing.:-(

--
I confess I enjoy democracy immensely. It is incomparably idiotic, and
hence incomparably amusing.
H. L. Mencken
Jun 27 '08 #5
Bob Nelson wrote, On 07/06/08 08:08:

<snip>
So look this over being brutal and merciless with your critique as I
try to rebuild my flabby C muscles:

#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

enum { MONTHS = 12, DAYS = 31 };
enum { JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV, DEC };
static const char *const months[] = { "JAN", "FEB", "MAR", "APR",
"MAY", "JUN", "JUL", "AUG",
"SEP", "OCT", "NOV", "DEC", };

int main(void)
{
typedef int month_type[DAYS];
typedef month_type *month_ptr_type ;
typedef int *day_ptr_type;

int calendar[MONTHS][DAYS];
Rather than the memset further down initialise calendar here
int calendar[MONTHS][DAYS] = {0};
month_ptr_type month_ptr;
size_t num_months;
size_t num_days_per_mo nth;

memset(calendar , 0, sizeof calendar);
assert(calendar[DEC][DAYS - 1] == 0);
As you say, a someone pointless assert. As are the others below.
month_ptr = calendar;
assert(sizeof *month_ptr == DAYS * sizeof(int));

num_months = sizeof calendar / sizeof *calendar;
assert(num_mont hs == MONTHS);

num_days_per_mo nth = sizeof *calendar / sizeof **calendar;
assert(num_days _per_month == DAYS);

for(; month_ptr < calendar + num_months; ++month_ptr) {
Rather than assigning monthptr several lines up I would assign it in the
for statement.
for (month_ptr = calendar;
month_ptr < calendar + num_months;
++month_ptr) {

Well, actually I would not use a pointer at all but instead in index use
it as an array.
day_ptr_type day_ptr = *month_ptr;
int month_num = (month_ptr - calendar + num_months) - num_months;
<snip>

This looks horrible complex for a simple problem. Having num_months
appear twice is somewhat suggestive of a poor job.

I've not reviewed the rest.
--
Flash Gordon
Jun 27 '08 #6
Ron Ford said:

<snip>
I use Dev-Cpp for quick and dirty C stuff and simply could not find a
means, from within the IDE, to pause a program before windows eats it up.
If you're running a console-style program, it makes sense to run it from a
console.
I ended up putting in a dos-shortcut where the executable lives, and that
works, but it misses the whole point of staying within an IDE during
development and testing.:-(
The whole point being... what, exactly?

--
Richard Heathfield <http://www.cpax.org.uk >
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Jun 27 '08 #7
Bob Nelson <bn*****@nelson be.comwrites:
After completing KNK2, my interest in C was reignited, prompting a
re-reading of Traister's dubious book on pointers. Then I dusted off
the fine ``C Traps and Pitfalls'' by Andy Koenig. Nowadays I primarily
work in PHP, Perl and C++. Consequently my C skills have atrophied.

So inspired by CT&P's ``calendar'' example on page 30, I decided to
brush up on some elementary C (although Koenig describes it as walking
``out on the ice'') with the little toy exercise below.
I don't know what KNK2 nor CT&P are, but I don't think that matters...

<snip>
So look this over being brutal and merciless with your critique as I
try to rebuild my flabby C muscles:

#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

enum { MONTHS = 12, DAYS = 31 };
enum { JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV, DEC };
static const char *const months[] = { "JAN", "FEB", "MAR", "APR",
"MAY", "JUN", "JUL", "AUG",
"SEP", "OCT", "NOV", "DEC", };

int main(void)
{
typedef int month_type[DAYS];
Some people object to typedefs (external declarations) inside
functions. I don't, but you may find people who do.

Array types are odd and although you use them correctly, some people
will consider it obfuscation to have them at all.
typedef month_type *month_ptr_type ;
Pointers to array types are even rarer. I don't think it makes
anything clearer in this program.
typedef int *day_ptr_type;
And finally, there is a school of thought that says the pointerlyness
of type (that it is a pointer) should not be hidden inside a typedef
unless you are making an opaque handle type. You are not, and I think
you've obscured things a little with all these typedefs. Note how you
feel you want to name the type with _ptr_ so you don't get lost. Much
better to let the * in the declaration do that for you.

For example, if you do need to have the pointed-to type named, try
this:

typedef int day_type;

and simply declare your variables:

day_type *dp;

but even that is overkill here, I feel.
int calendar[MONTHS][DAYS];
Having done all of the above, why not

month_type calendar[MONTHS];

If you've gone the effort of having an array type, why not use it?
month_ptr_type month_ptr;
size_t num_months;
size_t num_days_per_mo nth;

memset(calendar , 0, sizeof calendar);
assert(calendar[DEC][DAYS - 1] == 0);

month_ptr = calendar;
assert(sizeof *month_ptr == DAYS * sizeof(int));

num_months = sizeof calendar / sizeof *calendar;
assert(num_mont hs == MONTHS);

num_days_per_mo nth = sizeof *calendar / sizeof **calendar;
assert(num_days _per_month == DAYS);

for(; month_ptr < calendar + num_months; ++month_ptr) {
day_ptr_type day_ptr = *month_ptr;
int month_num = (month_ptr - calendar + num_months) - num_months;
Why not: 'int month_num = month_ptr - calendar;'?
int days_in_month;
int day_num;

switch(month_nu m) {
case FEB:
days_in_month = 28;
break;
case APR:
case JUN:
case SEP:
case NOV:
days_in_month = 30;
break;
default:
days_in_month = 31;
break;
}
I'd do this with an array rather than a switch.
for(day_num = 1; day_num <= days_in_month; ++day_num, ++day_ptr)
*day_ptr = day_num;
Slightly more idiomatic might be:

for(day_num = 0; day_num < days_in_month; ++day_num)
*day_ptr++ = day_num + 1;
}

for(month_ptr = calendar; month_ptr < calendar + num_months; ++month_ptr) {
int month_num = (month_ptr - calendar + num_months) - num_months;
see above.
int total_days_in_m onth = -1;
day_ptr_type day_ptr;

for(day_ptr = *month_ptr + num_days_per_mo nth - 1;
day_ptr *month_ptr; --day_ptr) {
if(*day_ptr) {
total_days_in_m onth = *day_ptr;
break;
}
}

printf("month %d (%s) has %d days\n",
month_num + 1, months[month_num], total_days_in_m onth);
}

return EXIT_SUCCESS;
}
Overall I am a little baffled. What is all the array setting for? Is
this part of a larger program that will do more? If I wanted the
output that you get, I'd just write:

#include <stdio.h>
#include <stdlib.h>

enum { MONTHS = 12, DAYS = 31 };
enum { JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV, DEC };

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

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

int main(void)
{
int month_num;
for (month_num = 0; month_num < MONTHS; month_num++)
printf("month %d (%s) has %d days\n",
month_num + 1, months[month_num], month_len[month_num]);
return EXIT_SUCCESS;
}

but I am sure that misses the point of your code.

--
Ben.
Jun 27 '08 #8

"Richard Heathfield" <rj*@see.sig.in validwrote in message
news:Qd******** *************** *******@bt.com. ..
Ron Ford said:

<snip>
>I use Dev-Cpp for quick and dirty C stuff and simply could not find a
means, from within the IDE, to pause a program before windows eats it up.

If you're running a console-style program, it makes sense to run it from a
console.
Yes, once it's finished. At that point you don't want the pause anymore.
>
>I ended up putting in a dos-shortcut where the executable lives, and that
works, but it misses the whole point of staying within an IDE during
development and testing.:-(

The whole point being... what, exactly?
The point being that it's supposed to be Integrated.

-- bartc
Jun 27 '08 #9
Bartc said:
>
"Richard Heathfield" <rj*@see.sig.in validwrote in message
news:Qd******** *************** *******@bt.com. ..
>Ron Ford said:
<snip>
>>
>>I ended up putting in a dos-shortcut where the executable lives, and
that works, but it misses the whole point of staying within an IDE
during development and testing.:-(

The whole point being... what, exactly?

The point being that it's supposed to be Integrated.
I guess we all have different ways of working. My way involves a lot of
xterm sessions. They all appear on the same screen, so I guess you could
call them integrated. No getchar call required, though.

--
Richard Heathfield <http://www.cpax.org.uk >
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Jun 27 '08 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

1
2279
by: Alexey V. Dmitriev | last post by:
Hi, ALL! Try to parse my XML doc with Xerces2-J (v.2.2.0), but ErrorHandler return errors a course of this proccess. All needed features were turn on. BTW, validation under XMLSpy tool passed successfully. What's wrong? Really these two tools (Xerces and XMLSpy) work on miscellaneous? Below the fragment of the scheme and XML-data itself are given. =================My XML Schema=================== <?xml version="1.0" encoding="UTF-8"?>...
8
2752
by: Mark A. Gibbs | last post by:
I have a string conversion function that looks something like this (apologies, but I cannot post the actual code): whar_t char_to_wchar(char); wstring to_wstring(const string& s) { wstring result(s.length(), '\0'); transform(s.begin(), s.end(), result.begin(), ptr_fun(char_to_wchar));
2
2293
by: P. Mellerin | last post by:
Hello, I have been searching online for a whole day and couldn't find an answer for this. I have this hyperlink server control: ------------------------------------------------------------------------------------ Design mode: <asp:HyperLink ID="MyHyperlink" Runat="server" NavigateUrl="#">Forms</asp:HyperLink>
6
1672
by: Bryan Dickerson | last post by:
(Newbie Alert!!) Is there a way to generate a Web Service from a WSDL file? Or does this not make sense? -- TFWBWY...A
0
1658
by: bturan | last post by:
Hi, I have 3 classes one of them is Point the other is line and the last one is triangle I'm trying to read the output of a mesh generator program. When I create the points and set the points with a constructor ; point::point(int listnumber,double x1, double y1,double z1) { x=x1; y=y1;
5
1441
by: arnuld | last post by:
I have created this program, it works, runs fine, no errors. I just wanted to have some comments or any advice: /* K&R2, exercise 5-5, page 107 * * write versions of the library function strncpy, strncat, and strncmp * which operate on at most 1st n characters of their argumen strings. for * example, strncpy(s, t, n) copies at most n characters from t to s. Full * descriptions are in Appendix B.
0
10208
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
10014
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
11632
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
11236
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
11412
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
10732
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
9932
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
8305
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
7471
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.