Is this acceptable (i.e., compliant) code?

  • Thread starter William L. Bahn
  • Start date
C

CBFalconer

Christopher said:
Unfortunately, that's the prescribed style at my place of
employment...

Time to scan the c.l.c archives and gather reasons to change the
style. Then write a very reasoned non-confrontational memo,
pointing out the errors that will be detected and the associated
time and money savings, and that it only need be implemented for
new and revised coding. This makes you a concerned company hero.
 
P

pete

pete said:
CBFalconer wrote:

I use the same rule, except that I think of "if, while, etc."
as keywords, and I follow keywords with a blank space always.

.... and I don't use a blank space after continue or break,
so maybe I was looking at it your way after all.
 
A

anonymous

#include said:
#include <stddef.h>
#include <limits.h>
static void printbits(void *mem, size_t size)
{
size_t i;
unsigned char mask;
char *p = mem;

for(i = 0; i < size; i++) {
for(mask = 1 << (CHAR_BIT - 1); mask; mask >>= 1)
putc((mask & p) ? '1' : '0', stdout);

putc(' ', stdout);
}
putc('\n', stdout);
}


The function above prints from LSB..MSB, I wanted to print in the reverse order
I tried using

for(i = size; i >= 0 ; i--)

But goes into an infinite loop because of unsigned int comparison, so I used

for(i = size; i != UINT_MAX; i--)

This works but is there a better way to do that?
 
C

CBFalconer

anonymous said:
#include <stdio.h>
#include <stddef.h>
#include <limits.h>
static void printbits(void *mem, size_t size)
{
size_t i;
unsigned char mask;
char *p = mem;

for(i = 0; i < size; i++) {
for(mask = 1 << (CHAR_BIT - 1); mask; mask >>= 1)
putc((mask & p) ? '1' : '0', stdout);

putc(' ', stdout);
}
putc('\n', stdout);
}


The function above prints from LSB..MSB, I wanted to print in the
reverse order I tried using

for(i = size; i >= 0 ; i--)

But goes into an infinite loop because of unsigned int
comparison, so I used

for(i = size; i != UINT_MAX; i--)

This works but is there a better way to do that?


i = size;
while (i--) {
....
}
 
P

pete

anonymous said:
#include <stdio.h>
#include <stddef.h>
#include <limits.h>
static void printbits(void *mem, size_t size)
{
size_t i;
unsigned char mask;
char *p = mem;

for(i = 0; i < size; i++) {
for(mask = 1 << (CHAR_BIT - 1); mask; mask >>= 1)
putc((mask & p) ? '1' : '0', stdout);

putc(' ', stdout);
}
putc('\n', stdout);
}


The function above prints from LSB..MSB, I wanted to print in the reverse order
I tried using

for(i = size; i >= 0 ; i--)

But goes into an infinite loop because of unsigned int comparison, so I used

for(i = size; i != UINT_MAX; i--)

This works but is there a better way to do that?


/* BEGIN bitstr.c */

#include <stdio.h>
#include <limits.h>

#define E_TYPE float
#define STRING " %s = %f\n"

typedef E_TYPE e_type;

void bitstr(char *, void const *, size_t);

int main(void)
{
e_type e, d;
char ebits[CHAR_BIT * sizeof e + 1], *s;

s = STRING;
e = 0.0f;
bitstr(ebits, &e, sizeof e);
printf(s, ebits, e);
((unsigned char*)&e)[sizeof e - 1] |= UCHAR_MAX / 2 + 1;
bitstr(ebits, &e, sizeof e);
printf(s, ebits, e);
for (e = -0.75f; 0.75 > e; e += 0.125) {
bitstr(ebits, &e, sizeof e);
printf(s, ebits, e);
}
for (d = 2; 20000 > d; d *= 2) {
for (e = d - 1; 0.75 > e - d; e += 0.5) {
bitstr(ebits, &e, sizeof e);
printf(s, ebits, e);
}
}
return 0;
}

void bitstr(char *str, const void *obj, size_t n)
{
unsigned mask;
const unsigned char *byte = obj;
char *const ptr = str;

while (n--) {
mask = ((unsigned char)-1 >> 1) + 1;
do {
*str++ = (char)(mask & byte[n] ? '1' : '0');
mask >>= 1;
} while (mask != 0);
}
*str = '\0';
}

/* END bitstr.c */
 
D

Dave Thompson

:

Change it so that main is last. You get all the same benefits for
the graders, and teach better habits.

Agree the same benefit -- and I don't understand anyway why it's
important to "find main" but not similarly find anything else. Better
habits is arguable -- there are benefits to both topdown and bottomup.
Ideally I would say teach (and practice) *both*, but the OP sounds
like he already has quite enough material he needs to cover.
Prototypes in headers are > for export.

But he didn't say to put them in a header; I understood him to mean
putting them above and below main() in the source (.c) file.
Personally I don't like the before/after split; if/when I want to do
topdown, I put *all* forward declarations before main(), or the other
top-level/entry routine(s) for a non-main module.
C requires declare before use, and duplicate
prototypes are an error source. It also discourages marking
non-exported routines as static.

Strictly speaking C89 does not require predeclaring functions in
certain limited cases, but ignore that; it's *abysmal* style.

Separate (forward) declarations are a little extra work to write and
maintain, and take up some space, but if you use prototypes for both
file-scope declaration and definition, as you should, any mismatch
will (is required to) be diagnosed.

I don't see how it "discourages" marking static=internal -- if
anything, by collecting the internal declarations in one place, while
the external declarations should be (as you noted earlier) in a header
file, I think it makes it slightly *easier*.

- David.Thompson1 at worldnet.att.net
 
F

Felipe Magno de Almeida

William said:
brushed up a bit.


file so the


computer science


so that the


function protorypes


of prior



Unfortunately no - most of them have basically none although it
varies quite a bit. The most frustrating part is the lack of
mathematical preparedness that even the brightest among them
have. Last semester I was working with my two sharpest students
after class talking about the properties of modulo arithmetic and
some other things such as logarithms to an arbitrary base and
both of them (from different high schools) remarked that they had
never actually seen the log function used to solve a problem -
that they had merely been taught that when you see it in an
equation you punch this button on your calculator. The calculator
generation.

I now spend the first two weeks covering what a positional
numbering system is and how to do basic math using one. The
pre-req for the course is Calc I, but very few of them have any
understanding of how to work with exponents or the relationship
between a logarithm and an exponent or even how do perform long
division. One of the first example problems I work in class when
we get to functions is writing a function that computes x^y
without using the pow() function. It gives me the opportunity to
link the problem statement to the basic logarithmic relationship,
solve it for the quantity of interest, and then write a simple
function to spit back the result. I warn them that a problem like
this is probably going to be on the exam. Come the exam, almost
no one gets it right and the most common attempt is to write a
for loop multiplying x by itself y times - even though in class I
stressed how repeated multiplication doesn't work for exponents
that are not positive integers and gave examples and on the test
the problem stressed that x was a positive floating point value
and y was any floating point value. The most frustrating part is
that, after getting dinged on one exam, walking though the exam
in detail when it is handed back, and warning them that problems
that people struggled with are likely to appear on the next exam,
the same thing happens.

Heck, I have a hard time getting them to understand the
difference between "the first positive number greater than a
hundred" and "the first positive number that has greater than a
hundred digits".



on the


trained to



A couple of the other responders provided tangible benefits for
locating main() last, in particular to make any recursive
relationships readily apparent. That's a demonstrable benefit I
can accept and express and impose, so I'm changing the style
standards accordingly.

The same with the return statement. As long as it was merely what
someone terms "ugly" I have a hard time changing my standards
since I saw a benefit. Any of these students that ever write much
code are likely to be doing it at the level that I do - namely
small programs to perform specific tasks as a minor part of
completely unrelated duties. I design full custom integrated
circuits - and occasionally I write a C program to perform some
utility or task to support that. So rules that get them to make
fewer mistakes when working at that level have merit.

But getting a different compiler message if you mistype the
return statement (I'm particularly prone to putting in 'retrun'
statements) is something worthwhile to look at and I can also see
the merit in emphasizing that return is not a function - but then
why should it be different than if(), while(), for(), and others
that are not functions but yet require the associated expression
to be in parentheses? Why should the return statement be
different? Just because the standard will let you get away
without the parens I don't see as being a good justification for
not including them.
wow, I dont see why so much problem.
Well, it is a standard here to teach Pascal to any engineer student(I am
CS student), but it has already been discussed about teaching C instead.
People decided it wasnt a good idea. But mathematical shouldnt be a
problem at all to any first year students, I think... mainly engineers,
that will see a lot of math later. Well, unleast it isnt here...

--
Felipe Magno de Almeida
Ciencia da Computacao - Unicamp
(e-mail address removed) - UIN: 2113442
Cause Rock and Roll can never die.
"if you want to learn something really well, teach it to a computer."
What is Communism?
Answer: "Communism is the doctrine of the conditions of the liberation
of the proletariat." (by Karl Marx)
 

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,780
Messages
2,569,611
Members
45,275
Latest member
Michaelachoda

Latest Threads

Top