Re: It Pays to Enrich Your C Skills



On 10 Mar 2006 05:09:21 GMT, "Ganny" <sgganesh@xxxxxxxxx> wrote in
comp.lang.c.moderated:

I love programming in C because its an interesting language and fun to
work with. Also, it pays (literal meaning also) to enrich your C
skills.

It pays even more to have better knowledge of C than you actually do,
before trying to make a post like this.

Here are 10 interesting programs (they are not toughest or promised to
be of any use, but interesting or just for curiosity). If you have more
interesting questions than this, do send it to me.

Check if you can score a perfect 10 (without using a compiler).

Have fun!

Cheers,
-Ganesh

1. Determine the output of the following program:

#include <stdio.h>

int main() {
int i = "This is C!" ;
puts(i);
}

2. Determine the output of the following program:

#include <stdio.h>

int main(){
printf("\a\b\c\d\e\f\g\h\i\j\k\l\m\
\n\o\p\q\r\s\t\u\v\w\x\y\z");
}

3. Determine the output of the following program:

#include <stdio.h>

struct bitfield {
signed int i : 1;
} bit1, bit2;

struct bitfield {
unsigned int i : 1;
} bit3, bit4;

int main() {
bit1.i = 1;
bit2.i = -1;
printf("signed values %d %d \n", bit1.i, bit2.i);
bit3.i = 1;
bit4.i = -1;
printf("unsigned values %u %u \n", bit3.i, bit4.i);
}

4. Determine the output of the following program:

#include <stdio.h>

// assume that sizeof(int) == 2 and

....that's 64 bits on an Analog Devices SHARC compiler, 32 bits on a
Texas Instruments 2812 compiler.

// sizeof(long) == 4 for this program

....and that's 128 and 64 bits respectively on the two compilers
mentioned above.

int main() {
printf("%d ", sizeof(32767)); // (1)
printf("%d ", sizeof(32768)); // (2)
printf("%d ", sizeof(-32767)); // (3)
printf("%d ", sizeof(-32768)); // (4)
}

5. For signed integers, which of the following relationships hold true?
(1) x >= 0 => -x <= 0
(2) x <= 0 => -x >= 0
(3) x > y => -x < -y

What relationship? There is no "=>" operator in C. This has no
meaning.

6. What does the following operation do (where x is an integer)?
(x) & -(x)

7. In the following code:

#include<stdio.h>

#define OBJ ???
int main() {
if (OBJ == &OBJ)
printf("equal\n");
}

What will you provide as #define for OBJ in ??? that the program is
valid and meaningful; also when the program is executed, it will print
"equal"?

8. Determine the output of the following program:

#include <stdio.h>

/* assume sizeof int to be 4 */
int i = 0123456789;
int j = 9876543210;
int main() {
printf("%d %d ", i, j);
}

9. Which is the only construct/type for which sizeof returns 0 in C?

10. The conditional operator (? :) is equivalent to if-then-else, which
is a ternary operator. Why is there no if-then binary (?) operator in
C?

Answers:

1)
This is C!

Actually, a conforming compiler must issue a diagnostic for this code.
If it also produces an executable, the behavior of the program is
undefined.

Though it is not assured that this will work, it works in almost all
platforms in practice because the size of int is equal to the size of a
pointer in almost all cases, and there is an implicit conversion
available
from pointer to integer type.

You are completely wrong in your last statement. There is absolutely
no implicit conversion from any pointer type to any integer type.

2)
Compiler Error: hex constants must have at least one hex digit.

There is no such thing as a "compiler error" in C, but in fact there
is no requirement at all that the compiler reach the point in the
source code where "\x" resides.

When the compiler reaches "\c", you have produced undefined behavior,
prior to C99, and unspecified behavior but the requirement for the
compiler to issue a diagnostic in C99.

In neither case is the compiler required to continue beyond that point
in the source.

\a is alert escape sequence, \b is backspace, \f is form-feed, \n is
new-line, \r is linefeed, \t is tab space, \v is vertical tab and \ at
the
end of a line is a line continuation character. \x is for hexadecimal
constants and it expects digits to follow after \x, and hence the
compiler
error.

3)
signed values -1 -1
unsigned values 1 1

In a signed bit-field size of 1 can store only one bit, the value
becomes a
sign bit. So, for both 1 and -1, the value is -1. For an unsigned
bit-field
of size 1, it can either store 1 or 0, so for both -1 and 1, it stores
1 and
hence the output is 1.

Actually, the correct value for bit4.i is 0, due to the rules of
unsigned integer arithmetic, but I would be really surprised to find a
compiler that generated that output. The wording about bit fields in
the standard that covers this is highly ambiguous.

4)
2 4 2 4

(1) 2. 32767 is in positive range of int, So it can be stored in an
int.
(2) 4. 32768 is not within the range of int, so it can't be stored in
an
int. It requires long so it prints 4.
(3) 2. Both -32767 and +32767 are in valid range of int, so we cannot
find
out if it is a negative integer constant or a constant expression

The last line above is pure gibberish. It is an integer constant
expression and cannot be anything else.

(4) 4. If -32768 were treated as negative integer constant it should
have
printed 2, because it is in valid integer range. +32768 cannot be
represented so promoted to integer and - operator is applied on it. So
the
only possibility is that this is a constant expression. Note that the
value -32768, when casted to int can be represented in an int without
any
loss of value.

Assuming 16 bits in an int, there is neither guarantee or requirement
that -32768 can be represented in an int. Even on 2's complement
implementations, INT_MIN is not required to be less than -32767. On
1's complement and signed magnitude implementations, there is no
possibility of representing -32768 in a signed 16-bit integer type.

Each of your examples is an integer constant expression. Given
INT_MAX equal to 32767, which you incorrectly imply is guaranteed by
saying that sizeof(int) == 2, then -32768 has the type signed long.

5)
(1) True for all x.
(2) Doesn't hold true (because it becomes false if x is INT_MIN).
(3) No. Consider x is -1, and y is INT_MIN:
-1 > INT_MIN // true
-1 > INT_MIN // false since INT_MIN == -INT_MIN


There are no meaningful answers since your examples are not actually
C.

6)
It returns the lowest bit set in an integer (which is a power of 2).

Not true when x is 0. Not true for signed integer types on sign
magnitude systems or 1's complement systems. On 1's complement
systems, the result might be a trap representation and produce
undefined behavior.

7)
The C language standard ensures that the expressions fn and &fn are
equal,
given fn is the name of a function. The function main is probably the
best
choice for #defining of OBJ (though any of the standard functions in C
library will do):

#define OBJ main

8)
Compiler Error, illegal digits '8' and '9' for base '8'

The prefix 0 in an integer constant indicates octal value. In octals,
use of
8 and 9 are not allowed, and hence the error.

9)
It is for the flexible array members (FLA) of C99. (Note that the
answer is
not sizeof(void) since it's a compiler error.)

#include <stdio.h>

struct flex {
int i;
int arr[];
} flex;

int main(int argc, char *argv[]) {
printf("size of flex.arr = %d", sizeof(flex.arr));

Did you compile this? If your compiler accepted it, it is a
non-standard extension. The sizeof operator can only be applied to
types or expressions, and not to the name of a structure member, which
is neither.

}
// prints:
// size of flex.arr = 0

C99 specifies that only the last element of a structure can be an FLA.
The
reason why sizeof applied to the structure ignores the FLA (and hence
the
FLA size is zero) is that, this makes the malloc call simple. That is
the
allocation is as follows:

struct flex *flex_ptr =
malloc(sizeof(struct flex) + num * sizeof(int));

Here note the change that it is num * sizeof(int) and not (num-1) *
sizeof(int), so, the malloc simple.

10)

Unlike if-then-else, the conditional operator can be part of
expressions; in
other words, the conditional operator has a type. The type of the
conditional operator is the second and the third (they should be of
same
type, or else they are promoted to be of same type). If there were a
binary
? operator, then, it cannot take part in expressions because it
wouldn't
have any type if the condition becomes false. So, there is no ?
operator in
C.

You appear to assume that all implementations of C are like those few
you are familiar with, for example:

CHAR_BIT is always 8

signed integer types use 2's complement representation

all compilers produce the same results that you are familiar with
when presented with certain examples of undefined behavior

all compilers provide the same non-standard extensions that yours
does

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://c-faq.com/
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.contrib.andrew.cmu.edu/~ajo/docs/FAQ-acllc.html
--
comp.lang.c.moderated - moderation address: clcm@xxxxxxxxxxxx -- you must
have an appropriate newsgroups line in your header for your mail to be seen,
or the newsgroup name in square brackets in the subject line. Sorry.
.



Relevant Pages

  • Re: Passing an already declarted array of structures!
    ... void LCD_PAINTSCREEN ... in above code by "int", ... If you guys see nothing wrong with the code, then I suppose its a compiler ... struct S { ...
    (microsoft.public.vc.language)
  • [MC++] Internal Compiler Error with /Ox
    ... ("NullReferenceException with value struct") ... __value struct Contours { ... int num_contours; ... Microsoft C/C++ Optimizing Compiler Version 13.10.3077 for .NET Framework ...
    (microsoft.public.dotnet.languages.vc)
  • Re: void * vs char *
    ... cast p to a (struct s*) to avoid a compile-time error. ... struct s {int a;}; ... function call consists solely of an identifier, and if no declaration ... And see what your compiler has to say. ...
    (comp.lang.c)
  • Re: Delay Routine: Fully-portable C89 if possible
    ... non-standard compiler with 8-bit shorts than a standard compiler with ... Embedded compilers sometimes support different sized types as extensions, beyond what is available through char, short int, int, long int and long long int. ... You mean padding the struct with extra elements, ... it avoids multiplies on lookups - multiplies can be costly on ...
    (comp.arch.embedded)
  • OT: Re: Perl Peeves
    ... I see the result of a test being used as an int. ... the compiler just assumed you knew what you were doing ... introduced to the language later, so void * was unheard of in most code. ... This didn't mean bool was special, declaring it just signaled to the ...
    (comp.lang.perl.misc)