5.7k views

Consider the following C program.

#include<stdio.h>
#include<string.h>

void printlength(char *s, char *t) {
unsigned int c=0;
int len = ((strlen(s) - strlen(t)) > c) ? strlen(s) : strlen(t);
printf("%d\n", len);
}

void main() {
char *x = "abc";
char *y = "defgh";
printlength(x,y);
}

Recall that $strlen$ is defined in $string.h$ as returning a value of type $size\_t$, which is an unsigned int. The output of the program is __________ .

edited | 5.7k views
+3

Let us assume our int  is of 3 bits then

value of binary 110  in unsigned int will be 6.( which is > 0)

value of binary 110  in signed int (or int ) will be -2. (In C int is represented in  2's compliment  representation)

One more thing -->

As you can see, (unsigned)0 - (unsigned)1 equals -1 modulo UINT_MAX+1, or in other words, UINT_MAX.

0

$(strlen(s)- strlen(t)) = 3-5 =-2$

But in C, when we do operation with two unsigned integers, result is also unsigned. ($strlen$ returns $size\_t$ which is unsigned in most systems). So, this result "$-2$" is treated as unsigned and its value is $INT\_MAX - 2$ (not sure about all systems, but at least on systems using $2$'s complement representation). Now, the comparison is between this large number and another unsigned number $c$ which is $0$. So, the comparison return TRUE here.

Even if '$c$' is declared as "$int$", while doing an operation with an unsigned int, it gets promoted to unsigned int and we get the same result.

Hence $(strlen(s)- strlen(t)) >0$ will return $1$ on execution thus the conditional operator will return the true statement which is $strlen(abc) =3$.

Ans should be $3$.
edited by
+3
@gaurav456

You should try this code. You were printing with %d which converts c to signed integer. So pick %ld which is big enough to take the large unsigned value that c has.

#include<stdio.h>
void main()
{

unsigned int a=3, b=5,c;
c=a-b;
long d=c;
printf("%ld",d);

}
0
ToBONGBIRDIE .. i appreciate your information regarding strlen() but I have a doubt ..

you said "strlen(s) - strlen(t) will yield unsigned-unsigned= unsigned".

Now  strlen(s) & strlen(t) produces separately positive values 3 and 5 respectively. Now as both 3 & 5 are unsigned... so (3-5) is not resulting (-2) ?

If it resulting (-2) then how that "unsigned int c" does not matter in the question?

0
@Arjun sir

Shouldn't it be

-2 mod (INT_MAX +1) = INT_MAX - 1 and   NOT INT_MA X - 2 , Considering 2's complement representation.
0

why after removing unsigned it is still  showing output as 3 .?

0
@VS

Yes i also agree that it should be INT_MAX-1 and not INT_MAX-2
0

@gaurav456 lets go to DELD/CO to understand output of your code

unsigned int a =3 , b=5,c;

c=a-b;

print(c);

first of all as sushmita said , there is no difference between representation of unsigned int and signed. it is just way cpu interpret this

suppose cpu using 8 bit for representation and used 2's compliment system

then -3 in signed representation is

0000 0011 (3)

1111 1100 (1s compliment)

1111 1101 (2s compliment)

a =3 will be represented as 0000 0011

b=5 will be represented as 0000  0101

a-b will be done by taking b's 2's compliment and adding it to a.

0000  0101 (b)

1111  1010 (b's 1s compliment)

1111 1011 (b's 2s compliment)

a-b =  0000 0011

+1111 1011

gives  1111 1110 (no carry generated)

Now rule says if carry generated ignore it (means answer is positive), but if no carry generated take 2's compliment(means answer is -ve , note that computer don't do take compliment , we take for our understanding purpose ) ( I wrote in just one simple sentence but there whole new concept behind it)

so here as no carry generated answer is -ve and to get t magnitude take compliment(2's )

0000 0010 (2)

hence output is -2

0

0
@gaurav456 you can print using "%u" instead of "%d" for this code which gives 4294967294 as difference between the strings and c.This makes it clear that the output will be 3.
0

Yes, it would be UINT_MAX-1.I mean -2 in unsigned integer would correspond to exactly this.

0
long is a signed integer in C and will display the same result as for int, '%u' should be used to display all unsigned int values.

Suppose  numbes are represented in 2's complement.

Then ,(strlen(s)- strlen(t)) gives -2.

Because it is unsigned ,its binary format will be in 2's complement

+2n-1-2 on n bit machine.

Just care here about that it will be positive and  condition become true,and length of first string gets printed which is 3.

+2

This is because of the unsigned int property which causes negative values to overflow into a large positive number
see this code snippet for better understanding

#include<stdio.h>
#include<string.h>

void printlength(char *s, char *t) {
unsigned int c = 0;
int len = ((strlen(s) - strlen(t)) > c )? strlen(s) : strlen(t);
printf("using standard int = %d\n", (strlen(s) - strlen(t)));
printf("using unsigned int = %u\n", (strlen(s) - strlen(t)));
printf("%d\n", len);
}

void main() {
char *x = "abc";
char *y = "defgh";
printlength(x,y);
}
0

Abhijith your example is very nice . I am just adding explanation to it .

 int len = ((strlen(s) - strlen(t)) > c )? strlen(s) : strlen(t);

 printf("using standard int = %d\n", (strlen(s) - strlen(t)));

here refer comment by @Bongbirdie to first answer as strlen returns unsigned integer .

bits that are stored in computer will be 1111 1110 How? (refer my comment to first answer)

Now if you use this value as signed integer (i.e %d) then it is -2 and if you use this value as unsigned it will return  4294967294 (here with my example it won't return as 4294967294  as i have taken just 8 bit to represent integer)

here it is taking two list of two legth

code like:

is the length of first list > lenght of 2nd list

then-> return the First list length

else

return 2nd list length

it is simply returning the length of larger string

here it is 5

so 5 should be the answer

0
I also thought the same Uddlpto, I ran it on Ideone, it gave 3.
http://ideone.com/QsOwvj
0
oh! again mark lost
0
I still don't understand how -2>0
0
but as per code it should be 5
+1

Aboveallplayer answer should be 3, because when you subtract an unsigned number from another unsigned it would result in a positive wrapped around number,

explanation:

When you work with unsigned types, modular arithmetic (also known as "wrap around" behavior) is taking place. To understand this modular arithmetic, just have a look at these clocks:

9 + 4 = 1 (13 mod 12), so to the other direction it is: 1 - 4 = 9 (-3 mod 12). The same principle is applied while working with unsigned types. If the result type is unsigned, then modular arithmetic takes place.

5 is the answer because ((3-5)>0 ) return 0 so len=strlen(t).

#include<stdio.h>
int main(){
printf("%d\n",((3-5)>0));
return 0;
}

[email protected]:~/socket_programming$gcc compare.c [email protected]:~/socket_programming$ ./a.out
0
+3
Good, but what you just answered showed a different thing - integer constants by default is signed in C.