## Sunday, July 16, 2006

### C questions ..(endian)

int x, y = 2, z, a;
if(x=y%2)
z=2;

The value of y%2 is 0. This value is assigned to x. The condition reduces to if (x) or in other words if(0) and so z goes uninitialized.
======
unsigned int i=10;
while(i-->=0)
printf("%u ",i);
10 9 8 7 6 5 4 3 2 1 0 65535 65534 ..Since i is an unsigned integer it can never become negative. So the expression i-- >=0 will always be true, leading to an infinite loop.
======
unsigned int i;
for(i=1;i>-2;i--)
printf("c aptitude");
i is an unsigned integer. It is compared with a signed value. Since the both types doesn't match, signed is promoted to unsigned value. The unsigned equivalent of -2 is a huge value so condition becomes false and control comes out of the loop.
======
static int i=i++, j=j++, k=k++;
i = 1, j = 1, k = 1, Since static variables are initialized to zero by default.
=======
if(a,b,x,y)
The comma operator has associativity from left to right. Only the rightmost value is returned and the other values are evaluated and ignored.
======
return(i++)
it will first return i and then increments. i.e. 10 will be returned.
======
struct point { int x; int y; };
Since structure point is globally declared x & y are initialized as zeros
======
while ((fgets(receiving array,50,file_ptr)) != EOF)
fgets returns a pointer. So the correct end of file check is checking for != NULL.
======
#define prod(a,b) a*b
main()
{
int x=3,y=4;
printf("%d",prod(x+2,y-1));
}
x+2*y-1 => x+(2*y)-1 => 10
enum{i=10,j=20,k=50};
printf("%d\n",++k);
Enumeration constants cannot be modified, so you cannot apply ++.
======
main()
{
signed char i=0;
for(;i>=0;i++) ;
printf("%d\n",i);
}
-128
======
if(~0 == (unsigned int)-1)
(unsigned int)-1 -> ffffffff , (unsigned int)-2 ->fffffffe
======
printf("%d",++i++);
Compiler error: Lvalue required in function main,++i yields an rvalue. For postfix ++ to operate an lvalue is required. printf("%d",(++i)++); is good
======
int i=5;
printf("%d“�,i=++i ==6);
1, The expression can be treated as i = (++i==6),
======
while (strcmp("some","some\0"))
Ending the string constant with \0 explicitly makes no difference. So some and some\0 are equivalent. So, strcmp returns 0 (false)
======
const int * a2
int const * a2
int * const a3
int const * const a4
The first two are the same. a2 is variable pointer to a constant integer, (a2 can change but *a2 cannot change)e.g.
int a=2;
a2 = &a; (legal)
*a2 = a; (illegal)
a3 is constant pointer to a variable integer (*a3 can change, but a3 cannot)
int b = 2;
int * const a3 = &b;
*a3 = a; (legal)
a3 = &a; (illegal)
a4 is constant pointer to a constant integer (*a4, a4, both cannot change)
*a4 = a; (illegal)
a4 = &a;(illegal)
Basically const applies to whatever is on its immediate left (other than if there is nothing there in which case it applies to whatever is its immediate right). Better to say, it is constant to its right:
(1)(2)'const' applies to int * rather than 'a2'
(3) 'cons' applied to 'a3' rather than to the value of a3
char str1[] = "abc";
char str2[] = "abc";
const char str3[] = "abc";
const char str4[] = "abc";
const char* str5 = "abc";
const char* str6 = "abc";
cout << str1="=" str3="=" str5="=">
Output: F F T,
======
int i=4,j=7; j = j || i++ && printf("YOU CAN");
printf("%d %d", i, j);
The boolean expression needs to be evaluated only till the truth value of the expression is not known. j is not equal to zero itself means that the expression's truth value is 1
======
register int a=2;
Compier Error: '&' on register variable
======
char *p="GOOD";
char a[ ]="GOOD";
printf("\n %d, %d, %d", sizeof(p), sizeof(*p), strlen(p));
printf("\n %d, %d", sizeof(a), strlen(a));
2 1 4 5 4
sizeof(p) => sizeof(char*) => 2,
sizeof(*p) => sizeof(char) => 1
When sizeof operator is applied to an array it returns the sizeof the array and it is not the same as the sizeof the pointer variable. Here the sizeof(a) where a is the character array and the size of the array is 5 because the space necessary for the terminating NULL character should also be taken into account. sizeof(a[10]) is 10.
======
#define DIM( array, type) sizeof(array)/sizeof(type)
int arr[10];
printf(â€œThe dimension of the array is %dâ€�, DIM(arr, int));
10.
The size of integer array of 10 elements is 10 * sizeof(int). The macro expands to sizeof(arr)/sizeof(int) => 10 * sizeof(int) / sizeof(int) => 10
======

int DIM(int array[])
{
return sizeof(array)/sizeof(int );
}
int arr[10];
printf("The dimension of the array is %d"�, DIM(arr));

1.
Arrays cannot be passed to functions as arguments and only the pointers can be passed. So the argument is equivalent to int * array (this is one of the very few places where [] and * usage are equivalent). The return statement becomes, sizeof(int *)/ sizeof(int) that happens to be equal in this case.
======
*(*(p+i)+j) is equivalent to p[i][j].
======

int i = 258;
int *iPtr = &i;
printf("%d %d", *((char*)iPtr), *((char*)iPtr+1) );

Answer: 2 1. The integer value 257 can be represented in binary as, 00000001 00000001. Remember that the INTEL machines are "small-endian" machines. Small-endian means that the Least Significant Bytes are stored in the lowest memory addresses and the higher order bytes are stored in higher addresses. The integer value 258 is stored in memory as: 00000001 00000010. the individual bytes are taken by casting it to char * and get printed. if i = 257+256=514, the answer is 1 2 (0000010 00000001). This is a very good one, *((char*)iPtr) points to low byte, *((char*)iPtr+1) points to high byte. (char *) used for byte. (update 6/20/2008)

Big-endian 0001 0011 0111 1111 -> little endian 1111 0111 0011 0001
Big-endian: The most significant byte (MSB) value, which is 0x0A in our example, is stored at the memory location with the lowest address, the next byte value in significance, 0x0B, is stored at the following memory location and so on. Motorola processors (those used in Mac’s) use "Big Endian" byte order.
The least significant byte (LSB) value, 0x0D, is at the lowest address. The other bytes follow in increasing order of significance.
1024 (0×00000400) stored in little endian machine 00 00 04 00, in big endian machine: 00 04 00 00

It is impossible to find endianess during the compile time, but we can use compile time flags "#ifdef _BIG_ENDIAN"

To find the endianess, try the following program:

int x = 1;

if (*(char *) &x == 1) // char *p = (char *)&x; if (p[0] == 1) little, if (p[1]==1) big

printf("little");

else ...

[update: 4/27/08][update: 06/20/08 for comment part]
======
char * str = "hello";
char * ptr = str;
while(*ptr++)
printf("%c\n", *(ptr-1));
Is there any difference between the two declarations, 1.int foo(int *arr[]) and
2.int foo(int *arr[2])?
NO. Functions can only pass pointers and not arrays. The numbers that are allowed inside the [] is just for more readability. So there is no difference between the two declarations.
======

void main()
{
printf ("sizeof (void *) = %d \n", sizeof( void *));
printf ("sizeof (int *) = %d \n�", sizeof(int *));
printf ("sizeof (double *) = %d \n", sizeof(double *));
printf ("sizeof(struct unknown *) = %d \n",, sizeof(struct unknown *));
}

all 2. The pointer to any type is of same size.
======
char a[4]="HELLO";
The array a is of size 4 but the string constant requires 6 bytes to get stored.
char a[6]="HELLO";