On Sun, 06 Feb 2005 14:18:09 +0530, in comp.lang.c , sathyashrayan
<look_at_the_bottom@nomail.com> wrote:
[color=blue]
>
>Following are the selected thread from the date:30-jan-2005 to
>31-jan-2005.[/color]
Sorry, but why did you do this? We don't need a digest here I think. What
useful purpose does it serve - anyone who wants to see what was taled about
on the 31st of Jan can go look in the google archives.
[color=blue]
> I did not use any name because of the subject is important.[/color]
A mistake - there's no way to know if the answer was good, bad or utter
dreck. The authori's name is often a good indicator.
[color=blue]
>You can get the original thread by typing the subject "string" in google
>comp.lang.c archives.[/color]
Indeed.
[color=blue]
>Hope this helps.Hope I am not bothering any one. am I?[/color]
Not bothering me, but its a waste of bandwidth and effort IMHO. There's
already a perfectly good FAQ, and google archives the posts. The FAQ is
edited too, to remove nonsense.[color=blue]
>
>=================================Start=========== ================
>subject: Return to Start of Line?
>
> Question:
> I'd like printf, the next printf, to return to the start of the
>line just printed. In other words, I want to keep print over the same
>portion of the screen again and again. 01, 02, 03, ... Is there some /X
>that does that?
>
> Answers:
>Depends on your output device. Usually \r. Don't forget to use
>fflush(f) when you haven't terminated a line with \n.
>
>#include <stdio.h>
>
> int main(int argc, char* argv[]) {
> for (size_t j = 0; j < 4; ++j)
> fprintf(stdout, "Hello world!\r");
> fprintf(stdout, "Hello world!\n");
> return 0;
> }
>[color=green]
> > gcc -Wall -std=c99 -pedantic -o main main.c
> > ./main[/color]
> Hello world!
>
>
>
>==============================End================ ======
>
>
>Subject: function to count number of set bits
>
>Question:
> Hi, I'm wondering if anyone knows if the following function will
>function properly as a set-bit counter on non 2s complement machines
>(as K&R2 implies).
>
>| int bitcount(unsigned x)
>| {
>| int count;
>|
>| for(count = 0; x != 0; count++, x &= (x-1))
>| ;
>|
>| return count;
>| }
>
>I can't think of a reason why this would fail on a 1s complement or
>sign-mag machine (and can't find a non 2s compliment machine to try it
>on). Is it portable as far as C is concerned?
>
>And also, if I declare a signed int in the main program and want to set
>the msb to 1, can I do this (32bit ints)?:
>
>int b = 0x8000000;
>/* is the 0x80000000 taken as an unsigned long constant or a signed
>int? */
>
>int count = bitcount(b);
>/* is this undefined- trying to send a negative int to bitcount
>function? */
>
>Answers:
>
>Answers:1)
>
>G Patel wrote:
>
>
>Hi, I'm wondering if anyone knows if the following function will
>function properly as a set-bit counter on non 2s complement machines
>(as K&R2 implies).
>
>| int bitcount(unsigned x)
>| {
>| int count;
>|
>| for(count = 0; x != 0; count++, x &= (x-1))
>| ;
>|
>| return count;
>| }
>[color=green]
> >I can't think of a reason why this would fail on a 1s complement or
> >sign-mag machine (and can't find a non 2s compliment machine to try it
> >on). Is it portable as far as C is concerned?[/color]
>
> It makes no difference what representation the machine
>uses for negative integers, because `x' cannot be negative!
>I see no portability or conformance problems in the code.
>
>[color=green]
> >And also, if I declare a signed int in the main program and want to set
> >the msb to 1, can I do this (32bit ints)?:[/color]
>[color=green]
> >int b = 0x8000000;[/color]
>
> You're missing a zero here, I believe.
>
>[color=green]
> >/* is the 0x80000000 taken as an unsigned long constant or a signed
> >int? */[/color]
>
> Neither: Given the assumption of 32 bits, the constant
>(with all seven zeroes) will be an `unsigned int'. Since the
>value of this constant is too large for plain `int', trying to
>convert it to `int' either produces an implementation-defined
>result or raises an implementation-defined signal. On most 32-bit
>implementations, `b' will be initialized to INT_MIN, -2147483648 --
>but the Standard doesn't actually guarantee this.
>
>[color=green]
> >int count = bitcount(b);
> >/* is this undefined- trying to send a negative int to bitcount
> >function? */[/color]
>
> No: conversion the other way, from signed to unsigned,
>is well-defined. However, the conversion might change the
>number of one-bits in the representation. For example, the
>representation of -1 on a signed magnitude machine has two
>one-bits. Converting this to `unsigned' produces the value
>UINT_MAX, which has at least sixteen one-bits. Avoiding such
>surprises is one of the reasons to stick to `unsigned' types
>for bit-fiddling.
>
>Answers:2)
>
>
>
>[color=green][color=darkred]
> > > Hi, I'm wondering if anyone knows if the following function will
> > > function properly as a set-bit counter on non 2s complement[/color][/color]
>machines[color=green][color=darkred]
> > > (as K&R2 implies).
> > >
> > > | int bitcount(unsigned x)
> > > | {
> > > | int count;
> > > |
> > > | for(count = 0; x != 0; count++, x &= (x-1))
> > > | ;
> > > |
> > > | return count;
> > > | }
> > >
> > > I can't think of a reason why this would fail on a 1s complement or
> > > sign-mag machine (and can't find a non 2s compliment machine to try[/color][/color]
>it[color=green][color=darkred]
> > > on). Is it portable as far as C is concerned?[/color]
> >
> > It makes no difference what representation the machine
> > uses for negative integers, because `x' cannot be negative!
> > I see no portability or conformance problems in the code.
> >[color=darkred]
> > > And also, if I declare a signed int in the main program and want to[/color][/color]
>set[color=green][color=darkred]
> > > the msb to 1, can I do this (32bit ints)?:
> > >
> > > int b = 0x8000000;[/color]
> >
> > You're missing a zero here, I believe.
> >[color=darkred]
> > > /* is the 0x80000000 taken as an unsigned long constant or a signed
> > > int? */[/color]
> >
> > Neither: Given the assumption of 32 bits, the constant
> > (with all seven zeroes) will be an `unsigned int'. Since the
> > value of this constant is too large for plain `int', trying to
> > convert it to `int' either produces an implementation-defined
> > result or raises an implementation-defined signal. On most 32-bit
> > implementations, `b' will be initialized to INT_MIN, -2147483648 --
> > but the Standard doesn't actually guarantee this.[/color]
>
>Thank you. Now I get it, I went and checked the C89 draft and found:
>
>The type of an integer constant is the first of the corresponding list
>in which its value can be represented. Unsuffixed decimal: int, long
>int, unsigned long int; unsuffixed octal or hexadecimal: int, unsigned
>int, long int, unsigned long int; suffixed by the letter u or U:
>unsigned int, unsigned long int; suffixed by the letter l or L: long
>int, unsigned long int; suffixed by both the letters u or U and l or L:
>unsigned long int .
>
>But I'm wondering how the "-" plays into any of this (for negative
>constants). Is the "-" part of the constant or is it just the constant
>with the - unary operator imparted on it.
>
>How would one explain these constants:
>
>-0xF , -077, -56
>
>
>No mention of "-" that go in front of constants in the standard. How
>does the "-" affect the constant (I imagine it just takes all the
>signed types in each list out of the picture).
>
>
>[I wonder what the authors of my C textbook was thinking when he named
>it: Teach yourself C in 24 hours ... they couldn't be more wrong]
>
>
>Answers:3)
>
>[color=green]
> > But I'm wondering how the "-" plays into any of this (for negative
> > constants). Is the "-" part of the constant or is it just the constant
> > with the - unary operator imparted on it.[/color]
>
>The latter.
>
>Answers:4)
>
>[color=green][color=darkred]
> > > But I'm wondering how the "-" plays into any of this (for negative
> > > constants). Is the "-" part of the constant or is it just the[/color][/color]
>constant[color=green][color=darkred]
> > > with the - unary operator imparted on it.[/color]
> >
> > The latter.[/color]
>
>Ok, so the - isn't part of the actual constant, only acts as a - unary
>operator. But what about constants that "fall" into a unsigned type.
>Wouldn't the whole expression be a sort of negative unsigned constant?
>
>Answers:5)
>[color=green][color=darkred]
> >> > But I'm wondering how the "-" plays into any of this (for negative
> >> > constants). Is the "-" part of the constant or is it just the[/color]
> > constant[color=darkred]
> >> > with the - unary operator imparted on it.
> >>
> >> The latter.[/color]
> >
> > Ok, so the - isn't part of the actual constant, only acts as a - unary
> > operator. But what about constants that "fall" into a unsigned type.
> > Wouldn't the whole expression be a sort of negative unsigned constant?[/color]
>
>Arithmetic in unsigned types "wraps around". A negative value in
>an unsigned type is changed into a positive one by adding the
>type's maximum value plus one until it is in range. Thus, -1u is
>equal to UINT_MAX.
>
>Answers:6)
>
>[color=green][color=darkred]
> >>> > But I'm wondering how the "-" plays into any of this (for negative
> >>> > constants). Is the "-" part of the constant or is it just the
> >>>>constant[/color][/color]
>[color=green][color=darkred]
> >>> > with the - unary operator imparted on it.[/color]
> >[color=darkred]
> >>
> >> The latter.[/color][/color]
>
>
>I don't think that is true. I think the "-" sign in front of an
>otherwise unadorned arithmetic constant is inherently part of the
>constant. If we considered the "-" to be an "add on" that works just
>as a unary - operator, then we would have to perform UAC/Promotion on
>assignments (where otherwise, an assignment has no promotion/UAC, just
>straight conversion to the type of the left operands).
>Where in the standard did you read this?
>
>Answers:7)
>
>
>[color=green][color=darkred]
> >>>>> > But I'm wondering how the "-" plays into any of this (for negative
> >>>>> > constants). Is the "-" part of the constant or is it just the[/color]
> >[color=darkred]
> >> constant[/color]
> >[color=darkred]
> >>>>> > with the - unary operator imparted on it.[/color][/color]
>[color=green][color=darkred]
> >>>> The latter.[/color][/color]
>[color=green][color=darkred]
> >> I don't think that is true. I think the "-" sign in front of an
> >> otherwise unadorned arithmetic constant is inherently part of the
> >> constant.[/color][/color]
>
>
>You're mistaken; see below.
>
>[color=green][color=darkred]
> >> If we considered the "-" to be an "add on" that works just
> >> as a unary - operator, then we would have to perform UAC/Promotion on
> >> assignments (where otherwise, an assignment has no promotion/UAC, just
> >> straight conversion to the type of the left operands).[/color][/color]
>
>
>Do you have an example where this matters? (Note that there are no
>integer constants for types shorter than signed or unsigned int.)
>
>[color=green][color=darkred]
> >> Where in the standard did you read this?[/color][/color]
>
>
>C99 6.4.4.1 defines the syntax of an integer constant; it doesn't
>allow for a leading sign.
>
>Answers:8)
>
>.... snip ...
>[color=green][color=darkred]
> >>>> If we considered the "-" to be an "add on" that works just as a
> >>>> unary - operator, then we would have to perform UAC/Promotion on
> >>>> assignments (where otherwise, an assignment has no promotion/UAC,
> >>>> just straight conversion to the type of the left operands).[/color]
> >[color=darkred]
> >>
> >> Do you have an example where this matters? (Note that there are no
> >> integer constants for types shorter than signed or unsigned int.)[/color][/color]
>
>
>Look at the way INT_MIN is usually defined in limits.h. For a 16
>bit 2's complement int machine, it would normally be (-INT_MAX -
>1). If it were written as -32768 it would create an overflow on
>input.
>
>Answers:9)
>[color=green][color=darkred]
> >> ... snip ...[/color][/color]
>
>[color=green][color=darkred]
> >>>>>>If we considered the "-" to be an "add on" that works just as a
> >>>>>>unary - operator, then we would have to perform UAC/Promotion on
> >>>>>>assignments (where otherwise, an assignment has no promotion/UAC,
> >>>>>>just straight conversion to the type of the left operands).[/color][/color]
>[color=green][color=darkred]
> >>>>Do you have an example where this matters? (Note that there are no
> >>>>integer constants for types shorter than signed or unsigned int.)[/color]
> >[color=darkred]
> >>
> >>
> >> Look at the way INT_MIN is usually defined in limits.h. For a 16
> >> bit 2's complement int machine, it would normally be (-INT_MAX -
> >> 1). If it were written as -32768 it would create an overflow on
> >> input.[/color][/color]
>
>
> Not an overflow, exactly, but a result with the wrong
>type and the wrong value. Since the constant is too large
>for `int' but within range for an `unsigned int' it would
>have the latter type; in effect it would be 32768u. The
>"negation" would, under the rules of unsigned arithmetic,
>reduce modulo 65536u to yield the value 32768u again. Thus
>you'd have the, er, "anomalous" condition INT_MIN > INT_MAX!
>
> Note that `(int)-32768' wouldn't work, since the value
>must be a constant expression and constant expressions can't
>contain cast operators.
>
>Answers:10)
>[color=green][color=darkred]
> >>>> Look at the way INT_MIN is usually defined in limits.h. For a 16
> >>>> bit 2's complement int machine, it would normally be (-INT_MAX -
> >>>> 1). If it were written as -32768 it would create an overflow on
> >>>> input.[/color]
> >[color=darkred]
> >>
> >> Not an overflow, exactly, but a result with the wrong
> >> type and the wrong value. Since the constant is too large
> >> for `int' but within range for an `unsigned int' it would
> >> have the latter type; in effect it would be 32768u. The
> >> "negation" would, under the rules of unsigned arithmetic,
> >> reduce modulo 65536u to yield the value 32768u again. Thus
> >> you'd have the, er, "anomalous" condition INT_MIN > INT_MAX!
> >>
> >> Note that `(int)-32768' wouldn't work, since the value
> >> must be a constant expression and constant expressions can't
> >> contain cast operators.[/color][/color]
>
>
>Casts are allowed in constant expressions although there are some
>restrictions which don't apply here. The problem with (int)-32768 where
>INT_MAX is 32767 and UINT_MAX is 65535 is that it is equivalent to
>(int)(32768U) i.e. you are trying to convert to a signed integer type a
>value that is not representable in that type. That's undefined in C90 and
>in C99 you get an implementation-defined value or signal.
>
>Answers:11)
>[color=green][color=darkred]
> >>>>>> Look at the way INT_MIN is usually defined in limits.h. For a 16
> >>>>>> bit 2's complement int machine, it would normally be (-INT_MAX -
> >>>>>> 1). If it were written as -32768 it would create an overflow on
> >>>>>> input.
> >>
> >>>>
> >>>> Not an overflow, exactly, but a result with the wrong
> >>>> type and the wrong value. Since the constant is too large
> >>>> for `int' but within range for an `unsigned int' it would
> >>>> have the latter type; in effect it would be 32768u. The
> >>>> "negation" would, under the rules of unsigned arithmetic,
> >>>> reduce modulo 65536u to yield the value 32768u again. Thus
> >>>> you'd have the, er, "anomalous" condition INT_MIN > INT_MAX!
> >>>>
> >>>> Note that `(int)-32768' wouldn't work, since the value
> >>>> must be a constant expression and constant expressions can't
> >>>> contain cast operators.[/color]
> >[color=darkred]
> >>
> >> Casts are allowed in constant expressions although there are some
> >> restrictions which don't apply here. The problem with (int)-32768 where
> >> INT_MAX is 32767 and UINT_MAX is 65535 is that it is equivalent to
> >> (int)(32768U) i.e. you are trying to convert to a signed integer type a
> >> value that is not representable in that type. That's undefined in[/color][/color]
>C90 and[color=green][color=darkred]
> >> in C99 you get an implementation-defined value or signal.[/color][/color]
>
>
>And if the implementation-defined value happens to be -32768, the
>implementation is free to use it as the definition of INT_MIN. (There
>are good reasons not to do so. Keeping <limits.h> in sync with the
>compiler might be non-trivial, and you might as well have a portable
>definition of INT_MIN if you can.)
>
>Answers:12)
>
>
>[color=green][color=darkred]
> >>And if the implementation-defined value happens to be -32768, the
> >>implementation is free to use it as the definition of INT_MIN. (There
> >>are good reasons not to do so. Keeping <limits.h> in sync with the
> >>compiler might be non-trivial, and you might as well have a portable
> >>definition of INT_MIN if you can.)[/color][/color]
>
>
>There is another good reason not to use a cast here. Suppose
>INT_MIN is in fact -32768 (numerically), and the implementation
>uses a cast in the "#define" for INT_MIN. Then consider:
>
> #if INT_MIN < (-2147483647 - 1)
> /* int is at least 32 bits */
> ...
> #endif
>
>When the compiler sees this during the preprocessing phase in which
>keywords have no meaning (because there are only pp-tokens, not
>yet any tokens), we get:
>
> #if ((some_pp_token)-32768) < (-2147483647 - 1)
>
>which is syntactically invalid and requires a diagnostic. My C99
>draft says, in part:
>
> [#1] The values given below shall be replaced by constant
> expressions suitable for use in #if preprocessing
> directives.
>
>(C89 has similar if not identical wording.)
>
>Answers:13)
>[color=green][color=darkred]
> >>> Look at the way INT_MIN is usually defined [...]
> >>
> >>
> >> Note that `(int)-32768' wouldn't work, since the value
> >> must be a constant expression and constant expressions can't
> >> contain cast operators.[/color]
> >
> >
> > Casts are allowed in constant expressions although there are some
> > restrictions which don't apply here. The problem with (int)-32768 where
> > INT_MAX is 32767 and UINT_MAX is 65535 is that it is equivalent to
> > (int)(32768U) i.e. you are trying to convert to a signed integer type a
> > value that is not representable in that type. That's undefined in C90 and
> > in C99 you get an implementation-defined value or signal.[/color]
>
>
> Sorry; sloppy language on my part. Casts are indeed
>permitted in "constant expressions" (6.6), but they are
>forbidden in the special form of "constant expression" the
>preprocessor can evaluate (6.10.1). INT_MIN and friends
>must be evaluable by the preprocessor (5.2.4.2.1), and so
>cannot be defined with casts.
>
>Answers:14)
>
>
>
>[color=green][color=darkred]
> >> I think the "-" sign in front of an
> >> otherwise unadorned arithmetic constant is inherently part of the
> >> constant. If we considered the "-" to be an "add on" that works just
> >> as a unary - operator, then we would have to perform UAC/Promotion on
> >> assignments (where otherwise, an assignment has no promotion/UAC, just
> >> straight conversion to the type of the left operands).
> >> Where in the standard did you read this?[/color][/color]
>
>
>Where did you find anything in the standard that talks about
>negative constants? The grammar shows `-' as a unary operator,
>not as part of a primary expression.
>
>I have no idea why you think this has anything to do with
>assignment.
>
>
>Answers:15)
>[color=green]
> >[color=darkred]
> >> I think the "-" sign in front of an
> >> otherwise unadorned arithmetic constant is inherently part of the
> >> constant. If we considered the "-" to be an "add on" that works just
> >> as a unary - operator, then we would have to perform UAC/Promotion on
> >> assignments (where otherwise, an assignment has no promotion/UAC, just
> >> straight conversion to the type of the left operands).
> >> Where in the standard did you read this?[/color]
> >
> >
> >
> > Where did you find anything in the standard that talks about
> > negative constants? The grammar shows `-' as a unary operator,
> > not as part of a primary expression.
> >[/color]
>#define EOF (-1)
>
>Is '-' part of a primary expression?
>
>#define LONG_MIN (-2147483647L-1L)
>
>How about here?
>
>I must be missing something. Help me here. Buy me a beer in Menlo Park.
>
>Answers:16)
>[color=green][color=darkred]
> >>>>>>I think the "-" sign in front of an
> >>>>>>otherwise unadorned arithmetic constant is inherently part of the
> >>>>>>constant. If we considered the "-" to be an "add on" that works just
> >>>>>>as a unary - operator, then we would have to perform UAC/Promotion on
> >>>>>>assignments (where otherwise, an assignment has no promotion/UAC,[/color][/color]
>just[color=green][color=darkred]
> >>>>>>straight conversion to the type of the left operands).
> >>>>>>Where in the standard did you read this?
> >>
> >>>> Where did you find anything in the standard that talks about
> >>>> negative constants? The grammar shows `-' as a unary operator,
> >>>> not as part of a primary expression.
> >>>>[/color]
> >[color=darkred]
> >> #define EOF (-1)
> >>
> >> Is '-' part of a primary expression?
> >>
> >> #define LONG_MIN (-2147483647L-1L)
> >>
> >> How about here?[/color][/color]
>
>
>Both of these are primary expressions because they're parenthesized.
>
>Without the parentheses, neither -1 nor -2147483647L-1L is a primary
>expression.
>
>Answers:17)
>
>[color=green][color=darkred]
> >>>> Where did you find anything in the standard that talks about
> >>>> negative constants? The grammar shows `-' as a unary operator,
> >>>> not as part of a primary expression.
> >>>>[/color]
> >[color=darkred]
> >> #define EOF (-1)
> >>
> >> Is '-' part of a primary expression?
> >>
> >> #define LONG_MIN (-2147483647L-1L)
> >>
> >> How about here?[/color][/color]
>
>
>1 primary-expression:
> identifier
> constant
> string-literal
> ( expression )
>
>You're trying to make some kind of pedantic point by saying that
>you parenthesized it, therefore it's a primary expression. But
>you know what my point is: there is no alternative listed as
>`- constant', nor is the negative sign part of `constant'
>itself (except perhaps as part of an exponent, etc.). There is
>no such thing as a negative constant, only a constant to which
>you apply a negating unary operator.
>
>Answers:18)
>
>
>[color=green][color=darkred]
> >> [...] There is
> >> no such thing as a negative constant, only a constant to which
> >> you apply a negating unary operator.[/color][/color]
>
>
> Three pettifogging counter-examples (two implementation-
>specific):
>
> enum { NEGATIVE = -42, POSITIVE = 42 };
> /* Henceforth, `NEGATIVE' is a negative constant. */
>
> '\x99'
> /* A constant whose value may be negative on some
> * implementations, depending on the value of CHAR_BIT
> * and the signedness of `char'.
> */
>
> 'ß'
> /* A constant whose value may be negative on some
> * implementations (and which might be utterly rejected
> * by some others, since the character is not in the set
> * mandated by the Standard).
> */
>
>
>
>Answers:19)
>
>
>
>
>[color=green]
> >[color=darkred]
> >>>> [...] There is
> >>>> no such thing as a negative constant, only a constant to which
> >>>> you apply a negating unary operator.[/color]
> >[color=darkred]
> >>
> >> Three pettifogging counter-examples (two implementation-
> >> specific):[/color][/color]
>
>[snip..]
>
>Okay, let me try again. There is no such thing as a negative
>integer-constant or floating-constant, but you may apply a
>negating unary operator to obtain a negative value.
>
>Anybody want to dispute *that*?
>
>Answers:20)
>[color=green][color=darkred]
> >>>> > > But I'm wondering how the "-" plays into any of this (for[/color][/color]
>
>negative
>[color=green][color=darkred]
> >>>> > > constants). Is the "-" part of the constant or is it just the[/color]
> >[color=darkred]
> >> constant[/color]
> >[color=darkred]
> >>>> > > with the - unary operator imparted on it.
> >>
> >>> >
> >>> > The latter.[/color][/color]
>[color=green][color=darkred]
> >>
> >> I don't think that is true. I think the "-" sign in front of an
> >> otherwise unadorned arithmetic constant is inherently part of the
> >> constant. If we considered the "-" to be an "add on" that works just
> >> as a unary - operator, then we would have to perform UAC/Promotion on
> >> assignments (where otherwise, an assignment has no promotion/UAC,[/color][/color]
>[color=green][color=darkred]
> >>just[/color][/color]
>[color=green][color=darkred]
> >> straight conversion to the type of the left operands).
> >> Where in the standard did you read this?[/color][/color]
>
>
>
>Actually it is treated as a unary - operator. In terms of C, the
>constant is just the arithmetic term without a sign. But of course,
>with the - in front of it, the negation is calculated at compile time,
>and the post-negated constant sits in memory along with corresponding
>assembly opcode(s) (calculation is not done at run time, there will be
>no evidence of the original positive constant within the instructions).
>But run-time instructions at assembly level are not a C issue.
>
>Answers:21)
>[color=green]
> >[color=darkred]
> >>> > I don't think that is true. I think the "-" sign in front of an
> >>> > otherwise unadorned arithmetic constant is inherently part of the
> >>> > constant.[/color]
> >[color=darkred]
> >>
> >> Actually it is treated as a unary - operator. In terms of C, the
> >> constant is just the arithmetic term without a sign. But of course,
> >> with the - in front of it, the negation is calculated at compile time,
> >> and the post-negated constant sits in memory along with corresponding
> >> assembly opcode(s) (calculation is not done at run time, there will be
> >> no evidence of the original positive constant within the instructions).[/color][/color]
>
>
>Not necessarily. Nothing in the Standard forbids implementations from
>computing the negation at run-time. Of course, nobody does so because
>it's simple to do at compile-time and potentially a great win, but this
>is not required.
>
>Answers:22)
>
>
>
>[color=green][color=darkred]
> >> Hi, I'm wondering if anyone knows if the following function will
> >> function properly as a set-bit counter on non 2s complement machines
> >> (as K&R2 implies).
> >>
> >> | int bitcount(unsigned x)
> >> | {
> >> | int count;
> >> |
> >> | for(count = 0; x != 0; count++, x &= (x-1))
> >> | ;
> >> |
> >> | return count;
> >> | }
> >>[/color][/color]
>
>Yes it will work.
>
>Heres two counters for 32 bit integers:
>
>int Count (unsigned int w)
>{
> w = (0x55555555 & w) + (0x55555555 & (w>> 1));
> w = (0x33333333 & w) + (0x33333333 & (w>> 2));
> w = (0x0f0f0f0f & w) + (0x0f0f0f0f & (w>> 4));
> w = (0x00ff00ff & w) + (0x00ff00ff & (w>> 8));
> w = (0x0000ffff & w) + (0x0000ffff & (w>>16));
> return w;
>}
>
>/* slightly faster */
>int Count (unsigned int w)
>{
> const unsigned int all1 = ~0;
> const unsigned int mask1h = all1 / 3 << 1;
> const unsigned int mask2l = all1 / 5;
> const unsigned int mask4l = all1 / 17;
> w -= (mask1h & w) >> 1;
> w = (w & mask2l) + ((w>>2) & mask2l);
> w = w + (w >> 4) & mask4l;
> w += w >> 8;
> w += w >> 16;
> return w & 0xff;
>}
>
>Answers:23)
>
>
>[color=green][color=darkred]
> >> Hi, I'm wondering if anyone knows if the following function will
> >> function properly as a set-bit counter on non 2s complement machines
> >> (as K&R2 implies).
> >>
> >> | int bitcount(unsigned x)
> >> | {
> >> | int count;
> >> |
> >> | for(count = 0; x != 0; count++, x &= (x-1))
> >> | ;
> >> |
> >> | return count;
> >> | }
> >>
> >> I can't think of a reason why this would fail on a 1s complement or
> >> sign-mag machine (and can't find a non 2s compliment machine to try[/color][/color]
>
>it
>[color=green][color=darkred]
> >> on). Is it portable as far as C is concerned?
> >>[/color][/color]
>
>If the intention is to call the function from either signed or unsigned
>int, then the code will not work on non-2s complement machiens for
>signed ints.
>
>Say for example you have -0 on a sign-mag or 1s comp. machine in an int
>variable y:
>
>Even though the y is not devoid of set bits on those machines, once the
>call is made to the function and the variable is converted from signed
>-> unsigned, C's rules will whipe out all the set bits (via -0 +
>UINT_MAX + 1). Your function will return 0 as the # of set bits
>because of the conversion that took place on the argument before
>function entry. This is an example of C's bias towards 2's complement
>machines (which is understandable because 2's complement is the "best"
>way to represent negative integers!).
>
>So the authors of K&R were probably warning you about calling the
>function with signed ints (not portable).
>
>
>Answers:24)
>
>[Given a bit-counting function that takes an unsigned int or unsigned
>long parameter...]
>
>[color=green][color=darkred]
> >>If the intention is to call the function from either signed or unsigned
> >>int, then the code will not work on non-2s complement machiens for
> >>signed ints.[/color][/color]
>
>
>Well, that depends on what one *wants*.
>[color=green][color=darkred]
> >>Say for example you have -0 on a sign-mag or 1s comp. machine in an int
> >>variable y:
> >>
> >>Even though the y is not devoid of set bits on those machines, once the
> >>call is made to the function and the variable is converted from signed
> >>-> unsigned, C's rules will whipe out all the set bits (via -0 +
> >>UINT_MAX + 1). Your function will return 0 as the # of set bits
> >>because of the conversion that took place on the argument before
> >>function entry.[/color][/color]
>
>
>Indeed it will. And yet, on such a machine, if -0 is produced by
>ordinary arithmetic (as opposed to being used to detect uninitialized
>variables, for instance), C requires that x==y be true even if x
>is -0 and y is +0. That is:
>
> x = <expression 1>;
> y = <expression 2>;
> if (x == y && bitcount(x) != bitcount(y))
> puts("how peculiar!");
>
>should never print the message, even if x is -0 and y is +0. So
>you might *want* bitcount() to return 0 in both cases.
>
>On the other hand, if you want to inspect the representation,
>rather than the value, of a variable, you can still write that:
>
> int representational_bit_count(unsigned char *p, int size);
> #define RBC(var) \
> representational_bit_count((unsigned char *)&(var), sizeof(var))
> ...
> if (x == y && RBC(x) != RBC(y))
> puts("while x==y, their representations differ");
>
>Note, however, that two identical and nonnegative values can still
>have differing representations, if some of the bits in the
>representations are padding bits.
>
>[color=green][color=darkred]
> >>This is an example of C's bias towards 2's complement
> >>machines (which is understandable because 2's complement is the "best"
> >>way to represent negative integers!).[/color][/color]
>
>
>While *I* am biased towards 2'sC I am not so sure C really is.
>C gives you the ability to inspect representations (via pointers
>and "unsigned char *"); it is up to you, the programmer, not to
>abuse it.
>
>
>Answers:25)
>
>
>[color=green][color=darkred]
> >> [Given a bit-counting function that takes an unsigned int or unsigned
> >> long parameter...]
> >>
> >>> >If the intention is to call the function from either signed or[/color][/color]
>[color=green][color=darkred]
> >>>unsigned[/color][/color]
>[color=green][color=darkred]
> >>> >int, then the code will not work on non-2s complement machiens for
> >>> >signed ints.[/color]
> >[color=darkred]
> >>
> >> Well, that depends on what one *wants*.
> >>[/color]
> >[color=darkred]
> >>> >Say for example you have -0 on a sign-mag or 1s comp. machine in an[/color][/color]
>[color=green][color=darkred]
> >>>int[/color][/color]
>[color=green][color=darkred]
> >>> >variable y:
> >>> >
> >>> >Even though the y is not devoid of set bits on those machines, once[/color][/color]
>[color=green][color=darkred]
> >>>the[/color][/color]
>[color=green][color=darkred]
> >>> >call is made to the function and the variable is converted from[/color][/color]
>[color=green][color=darkred]
> >>>>signed[/color][/color]
>[color=green][color=darkred]
> >>> >-> unsigned, C's rules will whipe out all the set bits (via -0 +
> >>> >UINT_MAX + 1). Your function will return 0 as the # of set bits
> >>> >because of the conversion that took place on the argument before
> >>> >function entry.[/color]
> >[color=darkred]
> >>
> >> Indeed it will. And yet, on such a machine, if -0 is produced by
> >> ordinary arithmetic (as opposed to being used to detect uninitialized
> >> variables, for instance), C requires that x==y be true even if x
> >> is -0 and y is +0. That is:
> >>
> >> x = <expression 1>;
> >> y = <expression 2>;
> >> if (x == y && bitcount(x) != bitcount(y))
> >> puts("how peculiar!");
> >>
> >> should never print the message, even if x is -0 and y is +0. So
> >> you might *want* bitcount() to return 0 in both cases.
> >>
> >> On the other hand, if you want to inspect the representation,
> >> rather than the value, of a variable, you can still write that:
> >>
> >> int representational_bit_count(unsigned char *p, int size);
> >> #define RBC(var) \
> >> representational_bit_count((unsigned char *)&(var),[/color][/color]
>[color=green][color=darkred]
> >>sizeof(var))[/color][/color]
>[color=green][color=darkred]
> >>[/color][/color]
>
>So what is truly the universal way of counting the respresentational
>bits on any platform? I see that you (Chris) use a char pointer
>somehow to cycle through the bytes, but will this catch all the extra
>bits used for handling overflow detection etc?
>[color=green][color=darkred]
> >>
> >> ...
> >> if (x == y && RBC(x) != RBC(y))
> >> puts("while x==y, their representations differ");
> >>
> >> Note, however, that two identical and nonnegative values can still
> >> have differing representations, if some of the bits in the
> >> representations are padding bits.
> >>[/color]
> >[color=darkred]
> >>> >This is an example of C's bias towards 2's complement
> >>> >machines (which is understandable because 2's complement is the[/color][/color]
>[color=green][color=darkred]
> >>>>"best"[/color][/color]
>[color=green][color=darkred]
> >>> >way to represent negative integers!).[/color]
> >[color=darkred]
> >>
> >> While *I* am biased towards 2'sC I am not so sure C really is.
> >> C gives you the ability to inspect representations (via pointers
> >> and "unsigned char *"); it is up to you, the programmer, not to
> >> abuse it.[/color][/color]
>
>
>Anyone know a truly universal function for counting all the setbits in
>a signed or unsigned number? I presume the receiving function would
>have to accept the parameter into a large signed integer (signed long
>long ?).
>
>
>Answers:26)
>
>
>[color=green][color=darkred]
> >> Hi, I'm wondering if anyone knows if the following function will
> >> function properly as a set-bit counter on non 2s complement machines
> >> (as K&R2 implies).
> >>[/color][/color]
>
>
>K&R2 was implying that the expression x &= (x-1) does not remove the
>rightmost set bit on all implementations - negative 'even' integers in
>sign-mag form will be left unchanged by x &= (x-1)
>
>[color=green][color=darkred]
> >>
> >> | int bitcount(unsigned x)
> >> | {
> >> | int count;
> >> |
> >> | for(count = 0; x != 0; count++, x &= (x-1))
> >> | ;
> >> |
> >> | return count;
> >> | }
> >>
> >> I can't think of a reason why this would fail on a 1s complement or
> >> sign-mag machine (and can't find a non 2s compliment machine to try[/color][/color]
>
>it
>[color=green][color=darkred]
> >> on). Is it portable as far as C is concerned?
> >>[/color][/color]
>
>
>The function itself is portable, because unsigned numbers have no
>issues.
>
>[color=green][color=darkred]
> >>
> >> And also, if I declare a signed int in the main program and want to[/color][/color]
>
>set
>[color=green][color=darkred]
> >> the msb to 1, can I do this (32bit ints)?:
> >>
> >> int b = 0x8000000;
> >> /* is the 0x80000000 taken as an unsigned long constant or a signed
> >> int? */
> >>
> >> int count = bitcount(b);
> >> /* is this undefined- trying to send a negative int to bitcount
> >> function? */[/color][/color]
>
>================================END============== ==============
>
>Subject: Is my memory is not enough?
>
>Question:
>
> Dear members:
>
>I am programming in C. I declare as follows but when running program,
>there is a fatal error appear:
>
>
>double a[255][255];
>double b[255][255];
>
>
>When I change it to
>
>double a[255][255];
>double b[255][100];
>
>
>then it works.
>
>I think the problem caused by the running out of memory.
>
>But I am wondering why I use malloc function, there is no error:
>------------------------
>double **a;
>double **b;
>
>a=malloc(255*255*sizeof(double));
>if(a==NULL)
>printf("there is an error");
>b= malloc(255*255*sizeof(double));
>if(a==NULL)
>printf("there is an error");
>-------------------------
>
>
>I think I am using the same volume of memory for both version. Why in
>the first case, the memory is insufficient of memory and in the other,
>it is big enough.
>
>One more thing, I need to use 2D array. I try the following but there
>is always error when I try to access to an element of the 2D array:
>
>
>double **a;
>double **b;
>
>a=malloc(255*255*sizeof(double));
>if(a==NULL)
>printf("there is an error");
>b= malloc(255*255*sizeof(double));
>if(a==NULL)
>printf("there is an error");
>
>a[1][1]=1;<----- the error occurs
>
>
>Pleas take a look and point out the error for me. or can you please
>suggest me other more effective methods to use 2D array?
>
>Thank you very much and look forward to your answer.
>SIncerly yours
>
>
>
>
>Answers:1)
>
>[color=green][color=darkred]
> >> Dear members:
> >>
> >> I am programming in C. I declare as follows but when running program,
> >> there is a fatal error appear:
> >>
> >>
> >> double a[255][255];
> >> double b[255][255];
> >>
> >>
> >> When I change it to
> >>
> >> double a[255][255];
> >> double b[255][100];
> >>
> >>
> >> then it works.
> >>
> >> I think the problem caused by the running out of memory.
> >>
> >> But I am wondering why I use malloc function, there is no error:
> >> ------------------------
> >> double **a;
> >> double **b;
> >>
> >> a=malloc(255*255*sizeof(double));
> >> if(a==NULL)
> >> printf("there is an error");
> >> b= malloc(255*255*sizeof(double));
> >> if(a==NULL)
> >> printf("there is an error");
> >> -------------------------
> >>
> >>
> >> I think I am using the same volume of memory for both version. Why in
> >> the first case, the memory is insufficient of memory and in the[/color][/color]
>
>other,
>[color=green][color=darkred]
> >> it is big enough.
> >>
> >> One more thing, I need to use 2D array. I try the following but there
> >> is always error when I try to access to an element of the 2D array:
> >>
> >>
> >> double **a;
> >> double **b;
> >>
> >> a=malloc(255*255*sizeof(double));
> >> if(a==NULL)
> >> printf("there is an error");
> >> b= malloc(255*255*sizeof(double));
> >> if(a==NULL)
> >> printf("there is an error");
> >>
> >> a[1][1]=1;<----- the error occurs
> >>[/color][/color]
>
>
>declare a and b like this
>
>double *a[255];
>double *b[255];
>
>
>You have to declare a & b as pointers to an array of 255 doubles,
>otherwise, how would the compiler know how much to "step over" when you
>double dereference. I'm giving you a very simplistic answer (I think
>you're a newbie). Reading the c.l.c FAQ will help you better
>understand the concepts. For now, you can start making use of your
>program by just changing the declarations to match what I have above.
>
>See:
http://www.eskimo.com/~scs/C-faq/s6.html for more details
>
>
>As for your conventionally allocated arrays, I am not sure what
>happened. Remember, malloc gives you access to a different type/area
>of memory than those conventionally allocated arrays would be place in.
>
>
>Answers:2)
>
>
>[color=green][color=darkred]
> >>declare a and b like this
> >>
> >>double *a[255];
> >>double *b[255];
> >>
> >>
> >>You have to declare a & b as pointers to an array of 255 doubles,[/color][/color]
>
>
>You have declared a and b as arrays of pointers, not as pointers to
>arrays. If you want a pointer to an array, you need
> double (*b)[255];
>
>[color=green][color=darkred]
> >>otherwise, how would the compiler know how much to "step over" when you
> >>double dereference. I'm giving you a very simplistic answer (I think
> >>you're a newbie). Reading the c.l.c FAQ will help you better
> >>understand the concepts. For now, you can start making use of your
> >>program by just changing the declarations to match what I have above.
> >>
> >>See:
http://www.eskimo.com/~scs/C-faq/s6.html for more details[/color][/color]
>
>Answers:3)
>
>[color=green][color=darkred]
> >>I think I am using the same volume of memory for both version. Why in
> >>the first case, the memory is insufficient of memory and in the other,
> >>it is big enough.[/color][/color]
>
>
>Most likely the memory is allocated on the stack in one case, and on
>the heap in the other. Your operating system probably has a limit on
>the stack size. How you change that limit will depend on the
>operating system; on unix systems the "limit" or "ulimit" command is
>what you want.
>
>Answers:4)
>[color=green]
> >[color=darkred]
> >>>>I think I am using the same volume of memory for both version. Why in
> >>>>the first case, the memory is insufficient of memory and in the other,
> >>>>it is big enough.[/color]
> >[color=darkred]
> >>
> >> Most likely the memory is allocated on the stack in one case, and on
> >> the heap in the other. Your operating system probably has a limit on
> >> the stack size. How you change that limit will depend on the
> >> operating system; on unix systems the "limit" or "ulimit" command is
> >> what you want.[/color][/color]
>
>
>Or you can just allocate the memory on the heap and not have to
>increase your stack limit every time you run the program.
>
>=================================END============= ========
>
>Subject: What does this code mean???
>
>Question:
>
> I am reading the code of a program from the examples, but really don't
>understand this one........
>
>int i,j;
>
>................................................. ....
>
>while (scanf("%d",&i),j)
>{
>........................................
>}
>
>So I think the question should become,
>how does the compiler evaluate the expression, (int i,int j)??
>(am I right?? 'cause scanf function returns an integer as I know)
>
>
>Answers:
>
>1)
>
>
>[color=green][color=darkred]
> >> I am reading the code of a program from the examples, but really don't
> >> understand this one........
> >>
> >> int i,j;
> >>
> >> .................................................. ..
> >>
> >> while (scanf("%d",&i),j)
> >> {
> >> .......................................
> >> }[/color][/color]
>
>
>Break it down like this:
>
>scanf("%d", &i), j
>
>The value returned by scanf is discarded and the whole expression
>evaluates to the value of j. A sequence point occurs
>at the comma. (See Annex C of the C Standard).
>
>The loop is reading in values and will continue executing
>while j is not 0.
>
>As an example, see what this does:
>
>/* comma.c */
>#include <stdio.h>
>
>int
>main (void)
>{
> int a, b = 6;
> int ret;
>
> ret = (a = 5, b);
>
> printf ("a: %d; ret: %d\n", a, ret);
>
> return 0;
>}
>
>Answers:2)
>[color=green]
> >[color=darkred]
> >>> > while (scanf("%d",&i),j)[/color][/color]
>
>[color=green][color=darkred]
> >> Break it down like this:
> >>
> >> scanf("%d", &i), j
> >>
> >> The value returned by scanf is discarded and the whole expression
> >> evaluates to the value of j. A sequence point occurs
> >> at the comma. (See Annex C of the C Standard).
> >>
> >> The loop is reading in values and will continue executing
> >> while j is not 0.[/color][/color]
>
>
>True, but I must say that this is an inadvisable way of using the comma
>operator. The scanf() call has nothing to do with whether or not the
>loop continues at all. This use of the comma is mere obfuscation.
>
>
>Answers:3)
>
>
>[color=green][color=darkred]
> >> True, but I must say that this is an inadvisable way of using the comma
> >> operator. The scanf() call has nothing to do with whether or not the
> >> loop continues at all. This use of the comma is mere obfuscation.[/color][/color]
>
>
>That's your opinion of course. I like this style because the return value of
>scanf is often ignored anyway and you dont need to put in 2 calls to scanf
>as in:
>
>scanf();
>while(j)
>{
> scanf();
>}
>
>
>
>Answers:4)
>[color=green][color=darkred]
> >>>> True, but I must say that this is an inadvisable way of using the[/color][/color]
>comma[color=green][color=darkred]
> >>>> operator. The scanf() call has nothing to do with whether or not the
> >>>> loop continues at all. This use of the comma is mere obfuscation.[/color]
> >[color=darkred]
> >>
> >> That's your opinion of course. I like this style because the return[/color][/color]
>value of[color=green][color=darkred]
> >> scanf is often ignored anyway[/color][/color]
>
>
>Unfortunately true. Consider however there are very few situations where
>ignoring the return value of scanf() isn't a bug.
>
>
>Answers:5)
>
>
>[color=green][color=darkred]
> >>[/color][/color]
>
>.... snip ...
>[color=green][color=darkred]
> >>
> >> Unfortunately true. Consider however there are very few situations
> >> where ignoring the return value of scanf() isn't a bug.[/color][/color]
>
>
>I rarely use scanf so am not sure, but are there any situations in
>which it isn't a bug?
>
>Answers:6)
>[color=green][color=darkred]
> >> ... snip ...[/color]
> >[color=darkred]
> >>>>
> >>>> Unfortunately true. Consider however there are very few situations
> >>>> where ignoring the return value of scanf() isn't a bug.[/color]
> >[color=darkred]
> >>
> >> I rarely use scanf so am not sure, but are there any situations in
> >> which it isn't a bug?[/color][/color]
>
>
>Only situations where you didn't care if the read operation failed or
>encountered end-of-file, and the scanf() just readss characters without
>writing values. scanf(fp, " ") to skip white-space perhaps in some odd
>circumstances. Not very likely but it is difficult to say that there
>is NO situation where this isn't a bug. Well actually easy to say, maybe I
>should and just wait for others to come up with the counterexamples.
>
>
>
>
>Answers:7)
>[color=green][color=darkred]
> >>>> ... snip ...
> >>
> >>>>>>
> >>>>>> Unfortunately true. Consider however there are very few situations
> >>>>>> where ignoring the return value of scanf() isn't a bug.
> >>
> >>>>
> >>>> I rarely use scanf so am not sure, but are there any situations in
> >>>> which it isn't a bug?[/color]
> >[color=darkred]
> >>
> >> Only situations where you didn't care if the read operation failed or
> >> encountered end-of-file, and the scanf() just readss characters without
> >> writing values. scanf(fp, " ") to skip white-space perhaps in some odd
> >> circumstances. Not very likely but it is difficult to say that there
> >> is NO situation where this isn't a bug. Well actually easy to say,[/color][/color]
>maybe I[color=green][color=darkred]
> >> should and just wait for others to come up with the counterexamples.[/color][/color]
>
>
>I'm not aware of any for scanf, but sscanf can certainly be legitimately
>used without checking the return value, because it leaves its arguments
>alone if it has no data so they default to the latest value. Silly
>example:
>
> #include <stdio.h>
> int main(void)
> {
> char buff[256];
> int x = 0;
> int y = 0;
> while (fgets(buff, 256, stdin))
> {
> sscanf(buff, "%d%d", &x, &y);
> printf("%d + %d = %d\n", x, y, x+y);
> }
> return 0;
> }
>
>I suppose one could use something similar with scanf() and check feof()
>after each call.
>
>Answers:8)
>[color=green]
> >[color=darkred]
> >>>>True, but I must say that this is an inadvisable way of using the comma
> >>>>operator. The scanf() call has nothing to do with whether or not the
> >>>>loop continues at all. This use of the comma is mere obfuscation.[/color]
> >[color=darkred]
> >>
> >>
> >> That's your opinion of course. I like this style because the return[/color][/color]
>value of[color=green][color=darkred]
> >> scanf is often ignored anyway [...][/color][/color]
>
>
> What else do you ignore? NULL values from malloc() and
>fopen()? Warning messages from compilers? STOP signs? Fire
>alarms?
>
> No wonder software sucks.
>
>
>Answers:9)
>
>
>[color=green][color=darkred]
> >> see the code below
> >> x=(scanf("%d",&i),j,k,l,......,z); /*x will hav the value of z*/
> >>
> >> u should that the comma separated expressions are evaluated from Left
> >> to Right and thats why the whole expression i.e. x, woud have a value
> >> of the rightmost expression i.e. z[/color][/color]
>
>
>No, that's not why. For example, the expressions separated by a string
>of && operators are _also_ evaluated from left to right, but the value
>of the whole expression is either 0 or 1, depending on any number of the
>expressions, no matter whether the relevant ones are 1, 3.14159265,
>&main, or any other non-zero value.
>
>Your conclusion is correct in so far that the Standard says of the ,
>operator that
>- its operands are evaluated in the order left first, then right;
>- because of the way its syntax it specified, it is left-to-right
> associative (which, in conjunction with the above, also means that a
> string of expressions separated by commas is evaluated left to right);
>- the value and type of the whole expression are those of the right
> argument.
>However, the third requirement does not follow by necessity from the
>first two at all.
>
>=================================END============= =============
>
>subject: array performance
>
>Question:
>
>Hi,
>
>I have on large threedimensional array
> int largeArray[1024][64][4];
>In a particular function I only need a part of this array
>So I'm using a new variable and assign it the follwoing way:
>
>int (*smallArray)[64][4];
>smallArray = &largeArray[42];
>
>Is the following code correct if I want to get the value of an element ?
>int x = smallArray[0][0];
>
>
>Is there a performance difference between retriveing many elements of the
>small and the large array in my function ?
>
>Answers:
>
>1)
>
>
>[color=green][color=darkred]
> >> I have on large threedimensional array
> >> int largeArray[1024][64][4];
> >> In a particular function I only need a part of this array
> >> So I'm using a new variable and assign it the follwoing way:
> >>
> >> int (*smallArray)[64][4];
> >> smallArray = &largeArray[42];
> >>
> >> Is the following code correct if I want to get the value of an[/color][/color]
>element ?[color=green][color=darkred]
> >> int x = smallArray[0][0];
> >>[/color][/color]
>
>I don't think so. smallArray is a pointer to a list of int [64][4] s. So
>smallArray[0] would be the first 2d array (&largeArray[42]), smallArray[1]
>would be the next (&largeArray[43]) and so on. So smallArray[0][0] actually
>returns a list of 4 integers, and you need (*smallArray)[0][0];
>
>However I have been programming in C for years, and had to think about this.
>This is the problem with mutli-dimensional arrays. Beyond the very basics,
>the syntax is horrible and confusing and even an experienced programmer will
>find it difficult to understand your program.
>[color=green][color=darkred]
> >>
> >> Is there a performance difference between retriveing many elements[/color][/color]
>of the[color=green][color=darkred]
> >> small and the large array in my function ?
> >>[/color][/color]
>
>Depends on the platform. Your huge array probably won't fit in a cache, but
>if you can arrange matters so that acesses that are continguous in memory
>are also close together in order, you might see some speed-up. Declaring a
>pointer to a small part of the array is unlikely to have an impact by
>itself, but it might help you organise the code efficently.
>
>
>Answers:2)
>
>[color=green][color=darkred]
> >>Hi,
> >>
> >>I have on large threedimensional array
> >> int largeArray[1024][64][4];[/color][/color]
>
>
>largeArray is an array of 1024 arrays of 64 arrays of 4 int.
>
>[color=green][color=darkred]
> >>In a particular function I only need a part of this array
> >>So I'm using a new variable and assign it the follwoing way:
> >>
> >>int (*smallArray)[64][4];[/color][/color]
>
>
>smallArray is a pointer to an array of 64 arrays of 4 int.
>
>[color=green][color=darkred]
> >>smallArray = &largeArray[42];[/color][/color]
>
>
>largeArray[42] is the n-th element (out of the possible 1024 elements)
>of largeArray. this element is an array of 64 arrays of 4 int.
>&largeArray[42] is the address of this element with the same type as
>smallArray.
>
>[color=green][color=darkred]
> >>
> >>Is the following code correct if I want to get the value of an element ?
> >>int x = smallArray[0][0];[/color][/color]
>
>
>No. smallArray is a pointer to the first of a series of objects, each
>of which is an array of 64 arrays of 4 int. smallArray[0] is the n-th
>such object pointed to and is therefore an array of 64 arrays of 4
>int. smallArray[0][0] is the n-th array (of the possible 64 arrays)
>and has type array of 4 int.
>
>As you have set it up, you need to use (*smallArray)[0][0].
>
>Alternatively, you could consider the following:
>
> largeArray[42] is a particularly object (out of the 1024 that
>largeArray consists of) with type 64 arrays of 4 int.
>
> In most contexts, the expression largeArray[42] evaluates to the
>address of the first element, that is the address of the first array
>of 4 int (out of the possible 64) with type pointer to array of 4 int.
>One exception to this rule (there are others) is when the expression
>is the operand of the & operators, as it is in your original code.
>
> If you code
> int (*smallArray)[4];
>you can assign to it with
> smallArray = largeArray[42];
>and then refer to individual integers with smallArray[i][j] which I
>find to be a much easier notation to read and to type.
>
>[color=green][color=darkred]
> >>
> >>Is there a performance difference between retriveing many elements of the
> >>small and the large array in my function ?
> >>[/color][/color]
>
>A quality of implementation issue which is not part of the language we
>discuss here. You can ask in a newsgroup where your compiler is
>discussed.
>
>=====================================END========= ==============
>
>
>
>Subject: help broke prog up into functions now not working
>
>Question:
>
> #include <stdio.h>
>#include <string.h>
>
>#define FALSE 0
>#define TRUE 1
>#define LINESIZE 255
>
>int setupoutfile(char filename[], FILE *outfile)
>{
> strcat(filename, ".js");
> outfile=fopen(filename, "w+");
> if(!outfile)
> {
> sleep(TRUE);
> outfile=fopen(filename, "w+");
> if(!outfile) return -1;
> }
>return 0;
>}
>
>int setupinfile(char filename[], FILE *infile)
>{
> infile=fopen(filename, "r+");
> if(!infile)
> {
> sleep(TRUE);
> infile=fopen(filename, "r+");
> if(!infile) return -1;
> }
>return 0;
>}
>
>int mymenu(FILE *infile, FILE *outfile)
>{
>char line[LINESIZE]="\0";
>int i=0;
>
> while(fgets(line, LINESIZE, infile)!=NULL)
> if(strstr(line, ".gif")!=NULL || strstr(line, ".jpg")!=NULL)
> {
> line[strlen(line)-1] = '\0';
> fprintf(outfile, "myImages[%d]=\"%s\"\n", i++, line);
> }
>return 0;
>}
>
>int main(int argc, char *argv[])
>{
>FILE *infile, *outfile;
>
> if(argc>2) setupoutfile(argv[2], outfile);
> if(argc>1) setupinfile(argv[1], infile);
> else
> {
> printf("mymenu infname basefolder -> basefolder.js\n");
> return -1;
> }
> mymenu(infile, outfile);
>return 0;
>}
>
>Answers:
>
>1)
>
>
>[color=green]
> > #include <stdio.h>
> > #include <string.h>
> >
> > #define FALSE 0
> > #define TRUE 1
> > #define LINESIZE 255
> >
> > int setupoutfile(char filename[], FILE *outfile)
> > {
> > strcat(filename, ".js");[/color]
>
>You are passing argv[2] as filename; there is no space left
>for ".js". You need an array of char or allocated storage
>of at least strlen(filename)+strlen(".js")+1 bytes.
>[color=green]
> > outfile=fopen(filename, "w+");
> > if(!outfile)
> > {
> > sleep(TRUE);[/color]
>
>sleep() is not a standard C function.
>[color=green]
> > outfile=fopen(filename, "w+");[/color]
>
>You are assigning the return value to outfile. Unfortunately,
>the value written to outfile will be lost to you as soon as
>you leave this function.
>Pass FILE **outfile to the function and assign to *outfile.
>[color=green]
> > if(!outfile) return -1;
> > }
> > return 0;
> > }
> >
> > int setupinfile(char filename[], FILE *infile)
> > {
> > infile=fopen(filename, "r+");[/color]
>
>
>same as above
>[color=green]
> > if(!infile)
> > {
> > sleep(TRUE);
> > infile=fopen(filename, "r+");
> > if(!infile) return -1;
> > }
> > return 0;
> > }
> >
> > int mymenu(FILE *infile, FILE *outfile)
> > { char line[LINESIZE]="\0";
> > int i=0;
> >
> > while(fgets(line, LINESIZE, infile)!=NULL)
> > if(strstr(line, ".gif")!=NULL || strstr(line, ".jpg")!=NULL)
> > {
> > line[strlen(line)-1] = '\0';[/color]
>
>
>Umh, what exactly do you think you are doing here?
>If line[strlen(line)-1] is _not_ '\n', you may very well discard
>the 'f' of gif or the 'g' of jpg.
>[color=green]
> > fprintf(outfile, "myImages[%d]=\"%s\"\n", i++, line);
> > }
> > return 0;
> > }
> >
> > int main(int argc, char *argv[])
> > {
> > FILE *infile, *outfile;
> >
> > if(argc>2) setupoutfile(argv[2], outfile);[/color]
>
>Here, with the changes suggested above, you need to pass
>a large enough buffer containing a copy of the string in argv[2]
>and &outfile.
>[color=green]
> > if(argc>1) setupinfile(argv[1], infile); else
> > {
> > printf("mymenu infname basefolder -> basefolder.js\n");
> > return -1;
> > }[/color]
>
>
>This logic is badly broken.
>
>What do you want? Probably:
> if (argc > 2) {
> char *buffer = malloc(strlen(argv[2])+4);
> if (!buffer) {
> fprintf(stderr,"Mem trouble\n");
> exit(EXIT_FAILURE);
> }
> strcpy(buffer, argv[2]);
> setupoutfile(buffer, &outfile);
> setupinfile(argv[1], &infile);
> free(buffer);
> }
> else {
> /* usual stuff */
> }
>
>By the way, if you do not want to return 0, rather use
>exit(EXIT_FAILURE) (and #include <stdlib.h>).
>[color=green]
> > mymenu(infile, outfile);
> > return 0;
> > }[/color]
>
>
>
>Answers:2)
>
>
>[color=green][color=darkred]
> >>>> outfile=fopen(filename, "w+");[/color]
> >[color=darkred]
> >> You are assigning the return value to outfile. Unfortunately,
> >> the value written to outfile will be lost to you as soon as
> >> you leave this function.
> >> Pass FILE **outfile to the function and assign to *outfile.[/color][/color]
>
>
>In this case you might just as well make it the return value of the
>function, with a null pointer return indicating a failure.
>
>Answers:3)
>
>
>[color=green]
> > {
> > FILE *infile, *outfile;[/color]
>
>
>How are these pointers initialized ?
>[color=green]
> > if(argc>2) setupoutfile(argv[2], outfile);
> > if(argc>1) setupinfile(argv[1], infile);[/color]
>
>
>Don't you meant
>
> if(argc>2) setupoutfile(argv[2], &outfile);
> if(argc>1) setupinfile(argv[1], &infile);
>
>or the like... Of course the prototypes of the functions have to be
>redesigned...
>
>int setupoutfile(char filename[], FILE **outfile)
>
>
>=================================END============= ========
>Subject: File handling
>
>Question:
>
>Hello everyone...........
>I have a problem on retriving a content of a binary file I wrote into.
>My program user structures, dynamic allocation of memory and files. I
>take the infomation into a dynamicaly allocated structure and then
>write it to a binary file using fwrite() with appending mode. I can
>retrive the data I wrote while the program is running. But if I stop
>the program and re-execute it I can't read the things I wrote to the
>file last time(only some vieard characters appear), but the the data I
>wrote this time appeard without any problem.
>How can I retrive the data I wrote to the file previousy.
>Souce code of the program I wrote is as follows,
>
>#include<stdio.h>
>#include<conio.h>
>#include<malloc.h>
>#include<string.h>
>#include<ctype.h>
>
>typedef struct student{
>char *name;
>int age;
>}stu;
>
>void stu_initializer(stu *p,FILE *fp);
>void print_stu(stu *p, FILE *fp);
>
>void main()
>{
>clrscr();
>stu *p;
>FILE *fp;
>
>//allocate memory for the structure
>p=(stu*)malloc(sizeof(stu));
>fp=fopen("stu.dat","a+b");
>
>stu_initializer(p,fp);
>fclose(fp);
>
>clrscr();
>fp=fopen("stu.dat","rb");
>print_stu(p,fp);
>
>
>fclose(fp);
>free(p);
>}////end main
>
>/////////////////////////////////////////////////////////////////////
>//set the information about the parties
>void stu_initializer(stu *p,FILE *fp)
>{
>int a;
>char buffer[81];
>
>
>
>do{clrscr();
>printf("Enter the student name: ");
>gets(buffer); fflush(stdin);
>//alocate memory for the stu name inside the structure
>
>
>p[0].name=(char*)malloc((strlen(buffer)+1)*sizeof(char ));
>strcpy(p[0].name,buffer);//copy the name to the structure
>
>//age of the student
>printf("\nEnter the index of the stu? ");
>scanf("%d",&p[0].age);
>fflush(stdin);
>//write to the file
>fwrite(p,sizeof(*p),1,fp);
>printf("\n\nAny more students?[Y][N] ");
>}while(toupper(getch())=='Y');
>
>clrscr();
>fflush(stdin);//clear the input buffer
>
>
>}//end function
>
>/////////////////////////////////////////////////////////////////////
>//print the stu list
>void print_stu(stu *p, FILE *fp)
>{
>printf("%s %s \n","Name","Age");
>while((fread(p,sizeof(*p),1,fp))==1)
>printf("%s %d\n",p[0].name,p[0].age);
>}
>
>
>
>Please Help me on this problem.......
>
>Answers:
>
>1)
>
>You are writing out a structure that has 1) a pointer and 2) an int. To
>be certain, your pointer might possibly point to a string, but at the
>moment you are only writing out the pointer to your string in
>memory--and once the application ends everything that was in memory
>will go away and your pointer when read back in the next time you run
>the application will just point to some random location in memory with
>who knows what data in it.
>
>One thing to note, once you do write out your strings, you will
>probably also want to write out their lengths into the file as well.
>Either that or you're going to have to read a whole bunch of strings in
>and then go searching about for the end of lines or \0s that you wrote
>out.
>
>Also, if you open your file with notepad (or whatever), you should be
>able to see any text that you have written into it. There will be some
>junk characters between the text (which will be the integers) but so
>long as there _is_ text you are one step ahead.
>
>
>
>Answers:2)
>
>
>[color=green][color=darkred]
> >> I have a problem on retriving a content of a binary file I wrote into.
> >> My program user structures, dynamic allocation of memory and files. I
> >> take the infomation into a dynamicaly allocated structure and then
> >> write it to a binary file using fwrite() with appending mode. I can
> >> retrive the data I wrote while the program is running. But if I stop
> >> the program and re-execute it I can't read the things I wrote to the
> >> file last time(only some vieard characters appear), but the the data I
> >> wrote this time appeard without any problem.
> >> How can I retrive the data I wrote to the file previousy.
> >> Souce code of the program I wrote is as follows,[/color][/color]
>
>
>Since there are that many errors in this program I mostly restrict
>my comments to the first occurence of an error...
>
>[color=green][color=darkred]
> >> #include<stdio.h>
> >> #include<conio.h>
> >> #include<malloc.h>[/color][/color]
>
>
>Both <conio.h> and <malloc.h> aren't standard C header files. Replace
><malloc.h> with <stdlib.h>. I have no idea what <conio.h> is supposed
>to do.
>
>[color=green][color=darkred]
> >> #include<string.h>
> >> #include<ctype.h>[/color][/color]
>
>[color=green][color=darkred]
> >> typedef struct student{
> >> char *name;
> >> int age;
> >> }stu;[/color][/color]
>
>[color=green][color=darkred]
> >> void stu_initializer(stu *p,FILE *fp);
> >> void print_stu(stu *p, FILE *fp);[/color][/color]
>
>[color=green][color=darkred]
> >> void main()[/color][/color]
>
>
>main() is always supposed to return an int. And it has either zero
>or two arguments, so make that
>
>int main( void )
>
>(or
>
>int main( int argc, char *argv[ ] )
>
>in case you are interested in the command line arguments).
>
>[color=green][color=darkred]
> >> {
> >> clrscr();[/color][/color]
>
>
>What's that supposed to do? It's not a standard C function.
>
>[color=green][color=darkred]
> >> stu *p;
> >> FILE *fp;[/color][/color]
>
>
>Unless you have a C99 compliant C compiler all variable definitions
>mus come before the first executable statement.
>
>[color=green][color=darkred]
> >> //allocate memory for the structure[/color][/color]
>
>
>Please use normal C style comments, i.e. '/*' and '*/', when you
>post in newsgroups. The C++ style comments were only introduced
>with the new C99 standard and often make it hard to see where a
>comment ends when a newsreader wraps long lines.
>
>[color=green][color=darkred]
> >> p=(stu*)malloc(sizeof(stu));[/color][/color]
>
>
>1) Check the return value of malloc().
>2) Drop the cast. It's not needed and will keep the compiler from
> complaining when you forgot to include the header file where
> malloc() is declared in (i.e. <stdlib.h>).
>
>[color=green][color=darkred]
> >> fp=fopen("stu.dat","a+b");[/color][/color]
>
>
>Check the return value of fopen().
>
>[color=green][color=darkred]
> >> stu_initializer(p,fp);[/color][/color]
>
>
>There's no declaration of this function (the definition only comes
>later), so the compiler can't check if you call it with the correct
>arguments,
>
>[color=green][color=darkred]
> >> fclose(fp);[/color][/color]
>
>[color=green][color=darkred]
> >> clrscr();
> >> fp=fopen("stu.dat","rb");
> >> print_stu(p,fp);[/color][/color]
>
>
>Again no declaration for the function...
>
>[color=green][color=darkred]
> >> fclose(fp);
> >> free(p);
> >> }////end main[/color][/color]
>
>
>Since main() must return an integer you're missing a return statement
>here.
>
>[color=green][color=darkred]
> >> /////////////////////////////////////////////////////////////////////
> >> //set the information about the parties
> >> void stu_initializer(stu *p,FILE *fp)
> >> {
> >> int a;
> >> char buffer[81];[/color][/color]
>
>[color=green][color=darkred]
> >> do{clrscr()[/color][/color]
>
>[color=green][color=darkred]
> >> printf("Enter the student name: ");[/color][/color]
>
>
>Unless the line ends with a '\n' it usually isn't printed immediately.
>You need a 'fflush(stdout);' after this.
>
>[color=green][color=darkred]
> >> gets(buffer); fflush(stdin);[/color][/color]
>
>
>Now, that's really horrible. First of all. Never, ever use gets().
>There is no way to keep the user from entering more character
>than fit into the buffer gets() puts them in. The function is
>broken by design. Use fgets() instead.
>
>Second, you can't fflush() stdin, you can only fflush() output
>channels.
>
>[color=green][color=darkred]
> >> //alocate memory for the stu name inside the structure[/color][/color]
>
>[color=green][color=darkred]
> >> p[0].name=(char*)malloc((strlen(buffer)+1)*sizeof(char ));[/color][/color]
>
>
>sizeof(char) is 1 by definition. And why do you use 'p[0]' here?
>Since 'p' isn't an array it would be clearer to use 'p->name'.
>
>[color=green][color=darkred]
> >> strcpy(p[0].name,buffer);//copy the name to the structure[/color][/color]
>
>[color=green][color=darkred]
> >> //age of the student
> >> printf("\nEnter the index of the stu? ");
> >> scanf("%d",&p[0].age);[/color][/color]
>
>
>Don't use scanf() when reading user input - if what the user enters
>isn't an integer you will get rather starnge results. Use fgets() to
>get the whole stuff and then use e.g. sscanf() to get the value,
>giving you a chance to check if there was an integer at all.
>
>[color=green][color=darkred]
> >> fflush(stdin);
> >> //write to the file
> >> fwrite(p,sizeof(*p),1,fp);[/color][/color]
>
>
>Now you try to write a structure, containing a pointer to a string.
>Once you read back in the file what the pointer points to is rather
>likely not the string that was at that address before. You have to
>write the string itself into the file, not just a pointer to were
>that string was sometime in the past. You might get away with that
>here by accident since you read back the structures within the same
>program (and since you never deallocate the memory for the strings
>once they aren't used anymore), but never if you try to read them
>back from a file in a newly started program.
>
>Moreover, you only write out as many bytes as a pointer to such a
>structure has because of the '*' in front of 'p'. But if you want
>to write out the structure you must fwrite() as many bytes as the
>structure is long.
>
>[color=green][color=darkred]
> >> printf("\n\nAny more students?[Y][N] ");
> >> }while(toupper(getch())=='Y');[/color][/color]
>
>
>getch() isn't standard C function, so I can't see if this here is
>correct...
>
>[color=green][color=darkred]
> >> clrscr();
> >> fflush(stdin);//clear the input buffer[/color][/color]
>
>
>No, you clear the input buffer by reading until nothing is in
>there anymore.
>
>[color=green][color=darkred]
> >> }//end function[/color][/color]
>
>[color=green][color=darkred]
> >> /////////////////////////////////////////////////////////////////////
> >> //print the stu list
> >> void print_stu(stu *p, FILE *fp)
> >> {
> >> printf("%s %s \n","Name","Age");
> >> while((fread(p,sizeof(*p),1,fp))==1)[/color][/color]
>
>
>This won't work for the multiple reasons given above.
>
>[color=green][color=darkred]
> >> printf("%s %d\n",p[0].name,p[0].age);
> >> }[/color][/color]
>
>
>As a rule writing out structures in binary form is a bad idea. Even
>if you get it right it will only work in case you read back the file
>on a machine with the same archtitecture and may require to have the
>programs for writing and reading where compiled with the same com-
>piler.
>
>=======================================END======= ================
>
>--
>"combination is the heart of chess"
>
> A.Alekhine
>
>Mail to:
> sathyashrayan AT gmail DOT com[/color]
--
Mark McIntyre
CLC FAQ <http://www.eskimo.com/~scs/C-faq/top.html>
CLC readme: <http://www.ungerhu.com/jxh/clc.welcome.txt>