Unsigned int to ascii in C

A place to discuss the implementation and style of computer programs.

Moderators: phlip, Prelates, Moderators General

Re: Unsigned int to ascii in C

Postby Yakk » Fri Feb 10, 2012 1:36 am UTC

Lines of code are not a useful measure of efficiency.

Doing something in fewer lines of code doesn't really do much. If clean, it can reduce the cognitive load required to figure out what is going on in a line of code. However, the design of pre and post increment in the context of C is iffy. There are serious quirks (sequence points etc) you do not need to learn.

In general, debugging code is harder than writing it. If you write code that is as clever as you can, you won't he smart enough to debug it.
One of the painful things about our time is that those who feel certainty are stupid, and those with any imagination and understanding are filled with doubt and indecision - BR

Last edited by JHVH on Fri Oct 23, 4004 BCE 6:17 pm, edited 6 times in total.
User avatar
Yakk
Poster with most posts but no title.
 
Posts: 10448
Joined: Sat Jan 27, 2007 7:27 pm UTC
Location: E pur si muove

Re: Unsigned int to ascii in C

Postby PM 2Ring » Fri Feb 10, 2012 1:53 am UTC

Little Richie wrote:
PM 2Ring wrote:It can also be written as
char s[11];
char *p;
p = s + 10;

If this is also the same, then I understand:
char s[11];
char *p;
p = s;
p = 10;

No that's different. The last line should be
p += 10;
or
p = p + 10;

Would you just use an indexed array and write to s[x], instead of the pointer?

Yes.

What are the advantages / disadvantages of pointers over indexes?

Pointers can lead to more succinct code. They can also lead to more efficient code, although modern compilers can often optimize such differences away.

The disadvantages are that it can take a while to understand them and to learn to use them properly.


Yakk wrote: There are serious quirks (sequence points etc) you do not need to learn.

I would've said that there are serious quirks (sequence points etc) that you do need to learn, but it's best to learn the basics first before learning how to deal with those extra complications.

Yakk wrote: In general, debugging code is harder than writing it. If you write code that is as clever as you can, you won't be smart enough to debug it.

I agree, and so did Brian Kernighan. :)
User avatar
PM 2Ring
 
Posts: 3297
Joined: Mon Jan 26, 2009 3:19 pm UTC
Location: Mid north coast, NSW, Australia

Re: Unsigned int to ascii in C

Postby phlip » Fri Feb 10, 2012 1:59 am UTC

Little Richie wrote:If this is also the same, then I understand:
char s[11];
char *p;
p = s;
p = 10;

Not quite, but if it was "p += 10;" or "p = p + 10;" then it would be the same.

Little Richie wrote:Actually, my mentor encourages making the code more efficient. I learned about " pre/post increment" in my first assignment, a bit counter. Personally, I'd also rather see it on one line than written in two.

Using pre/post increment within an expression doesn't make it more efficient than having it on two lines... it just makes the code more compact. The compiled result will usually be identical, or at least run at the same speed if in a slightly different order.
And even if it was more efficient, it would be only negligibly faster... not enough to be worth making the code harder to read.

Little Richie wrote:Would you just use an indexed array and write to s[x], instead of the pointer?

Yep, you'd have x start at 10 (instead of p starting at s+10) and then decrement it in the same way.

Little Richie wrote:What are the advantages / disadvantages of pointers over indexes?

Pointer arithmetic gives you a bit more flexibility (though it's flexibility you often don't need), while indexes are often easier to read.

It used to be the case that pointers could be very slightly faster than indexes (but only slightly, rarely enough to be worthwhile), but on modern CPUs they don't have that advantage, and pointers can actually be very slightly slower than indexes, as the compiler can optimise it better (but, again, rarely enough to be worth worrying about). Really, it can go either way depending on the situation, and not by much.

That said, it's still important to know how to use pointers in general, even if you don't use pointer arithmetic that often... things like arrays decaying into pointers, and manual memory management and the like are all things that are going to come up... and even in other languages, you're still going to have to deal with references and aliasing (ie multiple names pointing at the same object) and the like.
While no one overhear you quickly tell me not cow cow.
but how about watch phone?
User avatar
phlip
Restorer of Worlds
 
Posts: 7186
Joined: Sat Sep 23, 2006 3:56 am UTC
Location: Australia

Re: Unsigned int to ascii in C

Postby EvanED » Fri Feb 10, 2012 3:25 am UTC

Edit oops, I missed the 2nd page so only saw Yakk's response before writing this out. Oh well.

Little Richie wrote:
PM 2Ring wrote:char s[11];
char *p;
p = s + 10;

If this is also the same, then I understand:
char s[11];
char *p;
p = s;
p = 10;


What? No. That's no more right than saying x = 1 + 2; is the same as x = 1; x = 2;. (The difference, of course, being between 3 in the first case and 2 in the second.)

In the first case, p will point 10 chars past the beginning of s. It's the same as saying p = &s[10]. (Personally that's the way I'd write it if it were me.)

In the second case, it will set p to point to address 10. Which is not what you want... practically, it will segfault if you dereference it.


Actually, my mentor encourages making the code more efficient. I learned about " pre/post increment" in my first assignment, a bit counter. Personally, I'd also rather see it on one line than written in two.

As Yakk says, it won't be more efficient.

Take the first expression in PM2 Ring's code, *p-- = '\0';. (BTW, I like the '\0' instead of just the 0.) Testing with an old version of GCC (4.1.2) since that's what I happened to have most easily available, once you turn on optimization (-O2) it will generate identical code for PM2 Ring's version as the following:
Code: Select all
*p = '\0';
p--;


And that's not getting into the "premature optimization is the root of all evil" argument.

Personally, I and many other people think the latter is far clearer. I've been programming in C and C++ for a little more than a decade now (jeeze, I feel old), and am very familiar with the languages. And maybe I'm dumb (or more likely, rarely deal with expressions like that because neither I nor the people I work with write them), but even I have to stop and explicitly think about the order the decrement happens in. That's not good. Programming is hard enough already; don't make it harder than it has to be.

Furthermore, take the following code:
Code: Select all
#include <stdio.h>

void print_pair(int a, int b) {
    printf("a=%d, b=%d\n", a, b);
}

int main() {
    int x = 1;
    print_pair(x, x++);
    return 0;
}

What will it print?

Here's what you might be inclined to think:
Spoiler:
The first argument to print_pair will be 1, since that's x's initial value. Then the second argument increments x, but since it evaluates to the old value, that argument will be 1 as well. Thus it will print a=1, b=1.


Here's what will almost certainly happen with the system you're running.
Spoiler:
The second argument is evaluated first. It increments x, but evaluates to the old value, like we argued before. Thus the second argument to print_pair is 1. Then the first argument is evaluated. Now x has the value 2, because it was incremented before. Thus the program will print a=2, b=1.


Here's the actual answer:
Spoiler:
You don't know. Either one of the above can happen.


Edit again:
Spoiler:
Actually MSVC goes with the first option apparently. I expected it to follow the GCC behavior. Anyway, that just reinforces my point.


OK, new question. What happens if you change the call to
Code: Select all
print_pair(x++, x++)
?

Spoiler:
Now not only can it print either of the two things before, or do a couple other realistic options, it is allowed by the C standard to do anything it wants!

What you have done is invoked something called undefined behavior. It would be perfectly legal (if bad mannered and unrealistic) for your compiler to output a program which will reformat your hard drive if that line of code is executed.


PM 2Ring wrote:Well, it can be done without a pointer [. . .]

Would you just use an indexed array and write to s[x], instead of the pointer?
What are the advantages / disadvantages of pointers over indexes?

Yes, that's definitely possible.

Personally, I think array indices are easier to read. If you see a[i], you know immediately that you're indexing into array a. Now, you still have to go figure4 out where i is coming from in order to know what element is being accessed and if it's even a legal expression.

Now, you can't do everything with array indices, but for that reason among others I prefer them when they can easily express what you're doing. Iterating over an array is one of those times -- that's why you can do a[i] in the first place!
EvanED
 
Posts: 4141
Joined: Mon Aug 07, 2006 6:28 am UTC
Location: Madison, WI

Re: Unsigned int to ascii in C

Postby Little Richie » Fri Feb 10, 2012 4:14 am UTC

After reading all of that (a few times :D ) and playing around on my own some more, I have a much better understanding of pointers.
Thanks.

You have also changed my mind as far as pre/post increment.
I must have misconstrued his reasons for having me do that. This guy has been coding forever, he's even written his own Algebraic Assembly Language "terse". I'm sure he knows about the
EvanED wrote: undefined behavior

Perhaps his reasons were simply to let me know it exists.
With man gone, will there be hope for gorilla?
Check out my blog, my mission to save the world.
User avatar
Little Richie
 
Posts: 127
Joined: Tue Feb 05, 2008 3:02 am UTC
Location: Orlando, Florida

Re: Unsigned int to ascii in C

Postby PM 2Ring » Fri Feb 10, 2012 4:32 am UTC

Little Richie wrote:This guy has been coding forever,

Beware: some of us old-timers have developed bad habits that we occasionally inflict on the newbies. :)

FWIW, I've been using C since the early 1980s. It was the fifth language I learned (not counting a brief exposure to APL).

For the last few years I haven't done much C coding - I mostly write in Python these days, so my C skills aren't quite as sharp as they once were.
User avatar
PM 2Ring
 
Posts: 3297
Joined: Mon Jan 26, 2009 3:19 pm UTC
Location: Mid north coast, NSW, Australia

Re: Unsigned int to ascii in C

Postby jareds » Fri Feb 10, 2012 4:51 am UTC

Just to clarify, embedding a pre- or post-increment in an expression is not automatically undefined behavior; PM 2Ring did not use it in an undefined way; and even old timers who embed increments in expressions generally know better than to do so in an undefined way. However, the rules governing whether the behavior is undefined are somewhat complex, and I suspect we all think that it's best for you to not to have to worry about them yet.
jareds
 
Posts: 414
Joined: Wed Jan 03, 2007 3:56 pm UTC

Re: Unsigned int to ascii in C

Postby EvanED » Fri Feb 10, 2012 4:57 am UTC

Right; not everyone shares our disdain for that sort of use of the inc/decrement operators. Just look at the proclivity of C programmers to giggle with glee at the ability to write a string copying function as while(*p++ = *q++);.

It seems like the fondness for mixing in those operators is a lot greater with old-school C programmers than folks who have grown up recently. So I'd say it's just as likely that the fact that he's been coding forever would suggest that he would have a differing opinion. :-)

(And, of course, jareds is right. If you really do insist, following the rule that "if you say x++ then you can't use x anywhere else in that statement" is probably pretty close to C's rules for undefined behavior in that instance. And note that assignments are actually expressions; e.g. x = x++ is undefined behavior.)
EvanED
 
Posts: 4141
Joined: Mon Aug 07, 2006 6:28 am UTC
Location: Madison, WI

Re: Unsigned int to ascii in C

Postby Carnildo » Fri Feb 10, 2012 4:58 am UTC

Little Richie wrote:This guy has been coding forever,

If he's been programming forever, he may have learned C before the days of optimizing compilers. If you're using a compiler from the late 70s/early 80s, there's a decent chance that i++ is faster than i+=1. If your compiler was written in the mid-80s or later, it's almost certain to generate the same machine code for both cases.

(Technical details: most non-RISC CPUs have an "increment" instruction that simply adds 1 to a number, and a general-purpose "integer addition" instruction. With many older CPUs (including x86 CPUs prior to the 80486), the "increment" instruction takes one CPU cycle, while the "add" instruction takes several. A non-optimizing compiler is likely to map i++ to the "increment" instruction, while mapping i+=1 to the "add" instruction. An optimizing compiler will map both to whichever operation is faster on the target CPU.)
Carnildo
 
Posts: 2022
Joined: Fri Jul 18, 2008 8:43 am UTC

Re: Unsigned int to ascii in C

Postby EvanED » Fri Feb 10, 2012 5:03 am UTC

Carnildo wrote:
Little Richie wrote:This guy has been coding forever,

If he's been programming forever, he may have learned C before the days of optimizing compilers. If you're using a compiler from the late 70s/early 80s, there's a decent chance that i++ is faster than i+=1. If your compiler was written in the mid-80s or later, it's almost certain to generate the same machine code for both cases.

One more point inspired by this. We're not saying avoid the ++ and -- operators, just to put them in their own statement. For instance, this is hunky-dory:
Code: Select all
*p = '\0';
++p;

In fact, I'd rather see p++ than p += 1 personally, especially if p is a pointer.
EvanED
 
Posts: 4141
Joined: Mon Aug 07, 2006 6:28 am UTC
Location: Madison, WI

Re: Unsigned int to ascii in C

Postby Little Richie » Fri Feb 10, 2012 5:50 am UTC

EvanED wrote:
Carnildo wrote:
Little Richie wrote:This guy has been coding forever,

If he's been programming forever, he may have learned C before the days of optimizing compilers. If you're using a compiler from the late 70s/early 80s, there's a decent chance that i++ is faster than i+=1. If your compiler was written in the mid-80s or later, it's almost certain to generate the same machine code for both cases.

One more point inspired by this. We're not saying avoid the ++ and -- operators, just to put them in their own statement. For instance, this is hunky-dory:
Code: Select all
*p = '\0';
++p;

In fact, I'd rather see p++ than p += 1 personally, especially if p is a pointer.


Yes, got that. I think p += 1 is disgusting.

PM 2Ring wrote:Beware: some of us old-timers have developed bad habits that we occasionally inflict on the newbies.

Haha, I'll keep an eye out. My main use of the fora is to get general help that I can apply to specific situations. The crossfire of conflicting opinions actually helps a lot too, rather than one person saying something and me taking it as true, I get a deeper look into the root of the problem.
With man gone, will there be hope for gorilla?
Check out my blog, my mission to save the world.
User avatar
Little Richie
 
Posts: 127
Joined: Tue Feb 05, 2008 3:02 am UTC
Location: Orlando, Florida

Re: Unsigned int to ascii in C

Postby PM 2Ring » Fri Feb 10, 2012 8:39 am UTC

EvanED wrote:Right; not everyone shares our disdain for that sort of use of the inc/decrement operators. Just look at the proclivity of C programmers to giggle with glee at the ability to write a string copying function as while(*p++ = *q++);.

* giggles *

It seems like the fondness for mixing in those operators is a lot greater with old-school C programmers than folks who have grown up recently. So I'd say it's just as likely that the fact that he's been coding forever would suggest that he would have a differing opinion. :-)

I blame the copious examples of such constructions in K & R.

(And, of course, jareds is right. If you really do insist, following the rule that "if you say x++ then you can't use x anywhere else in that statement" is probably pretty close to C's rules for undefined behavior in that instance. And note that assignments are actually expressions; e.g. x = x++ is undefined behavior.)

Argh! It burns!
User avatar
PM 2Ring
 
Posts: 3297
Joined: Mon Jan 26, 2009 3:19 pm UTC
Location: Mid north coast, NSW, Australia

Re: Unsigned int to ascii in C

Postby Sandor » Fri Feb 10, 2012 3:32 pm UTC

PM 2Ring wrote:It's a Good Idea to include headers for any library functions that your program uses. You're using printf(), so you should include <stdio.h>, otherwise the compiler will have to guess what the argument types of printf() are. Luckily, automatic promotion makes everything work properly in this instance, but you shouldn't rely on that.

Variable argument functions like printf always have to have a valid declaration in scope, so if you want to avoid undefined behaviour you must include <stdio.h>. Without a declaration, the compiler will (or at least, is allowed to) assume printf is a non-vararg function, and the calling conventions for non-vararg functions and vararg functions may be different.

PM 2Ring wrote:This process may look a bit dodgy. What happens if we're converting a large number that totally fills s? At the end of the loop, p points to a memory address that's outside of s. Fortunately, that's ok - to permit algorithms like this one, the C standard says that pointer arithmetic is allowed to reference the location just before or just after an array. But it's definitely not wise to dereference a pointer when it points to a location that you don't legitimately own.

The C standard only says that pointer arithmetic is allowed to reference one past the end of an array. I don't think one before the start is defined.
Sandor
 
Posts: 117
Joined: Sat Feb 13, 2010 8:25 am UTC

Re: Unsigned int to ascii in C

Postby PM 2Ring » Sat Feb 11, 2012 2:35 am UTC

Sandor wrote:
PM 2Ring wrote:This process may look a bit dodgy. What happens if we're converting a large number that totally fills s? At the end of the loop, p points to a memory address that's outside of s. Fortunately, that's ok - to permit algorithms like this one, the C standard says that pointer arithmetic is allowed to reference the location just before or just after an array. But it's definitely not wise to dereference a pointer when it points to a location that you don't legitimately own.

The C standard only says that pointer arithmetic is allowed to reference one past the end of an array. I don't think one before the start is defined.

It appears that you are correct, Sandor.

Sorry.
User avatar
PM 2Ring
 
Posts: 3297
Joined: Mon Jan 26, 2009 3:19 pm UTC
Location: Mid north coast, NSW, Australia

Previous

Return to Coding

Who is online

Users browsing this forum: No registered users and 6 guests