+65 votes
9.9k 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 | 9.9k views
+5

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.

+2

Phalkey have you read the last para of question? Answer is there

0
I saw in a video which explain by saying that subtraction of 2 no (either of one is unsigned )then the ans will be positive? Is this correct?
0
You are right,

#include<stdio.h>
#include<string.h>
void main()
{
unsigned int a=2;
unsigned int b=3;
printf("%u", a-b);
}
Output: positive

#include<stdio.h>
#include<string.h>
void main()
{
unsigned int a=9;
int b=108;
printf("%u", a-b);
}
Output: positive

#include<stdio.h>
#include<string.h>
void main()
{
unsigned int a=9;
unsigned int b=108;
printf("%d", a-b);
}

Output: negative
0

i got the point the o/p would be

around 4294967197

but in above question we are though returning unsigned number but subtraction is taking place between two signed integers(this result has no relation with the unsigned no)  then  we are comparing  with unsigned . no..i  am still not clear about the particular question?

how a negative no can be transformed into positive when comparing with unsigned no ..does n't make any sense ??

+1
For clearing  your doubt , read the comments in answer below

## 8 Answers

+80 votes
Best answer
$(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$.
by
edited by
0
ok means len here promoted to unsigned int.
+45
The Answer is 3 but I found somewhat a different explanation.
Even if 'unsigned int c' is not given, ((strlen (s) - strlen (t)) > c) would return true(and print 3 as output) since strlen() function always returns unsigned value. So, strlen(s) - strlen(t) will yield unsigned-unsigned= unsigned value which, upon being compared with c( even if it is signed), would return TRUE( and print 3 ) since c will be converted to unsigned.

So, having unsigned/siged int c doesn't make much of a dfference.
+9
You are correct.
+1

the definition of strlen function is given in string.h header file and the output of the strlen function retrun a value of type size_t form and size_t is a unsigned integer . so in each case  ((strlen(s) - strlen(t)) > c) return a unsigned value, it is not matter that whether c is given unsigned or not.

if c is not given unsgined then answer also will be same .

+3

Binary operations between different integral types are performed within a "common" type defined by so called usual arithmetic conversions (see the language specification, 6.3.1.8)

C Language Specification URL : www.open-std.org/jtc1/sc22/wg14/www/docs/n1124.pdf

So here (strlen(s)-strlen(t)) which is coming as -2 is converted to first unsigned int (which evaluates to INT_MAX-2) and then it is compared with c(c being unsigned int) which is 0.

The result of the boolean expression in program goes true and strlen(s) is selected for output which prints output as 3.

+2

IIn above case it returns -2 .I think it should return 2 .Do not understand why this is happening .We discussed that arithmetic calcuation between unsigned is always positive.

0
size_t strlen( const char *s );

Thanx that was an eye opener

0

Here, we compare length of pointer because s and t are char type pointer. But all type of pointer have same size then why we get length of string and when i try to print strlen(*y) i got error . why?

could you explain ?

+7
@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?

if you can please reply..
+1
@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.
+1

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)

now coming to your question

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

+1

@once_2019  read comment of  @Bongbirdie

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.
+2

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

And also it is very logical.

Suppose I take  unsigned int as 1 Byte data.

So, Minimum value would be 0000 0000.

Now suppose I do -1 on this, this would wrap to the highest value=1111 1111

Now to this again I do -1, then it would become 1111 1110, Which is exactly 1 less than the maximum value.

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.
0

@Arjun Sir if we are considering int of 2 bytes than -2 will be stored as 11111111 1111 1110 ,

which will be taken as positive value in the case of unsigned..

am i correct?

0
+9 votes

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.

+3 votes
Since the question stresses that the function returns an UNSIGNED number. There has to be a thing around that. Which is

An unsigned number can never be negative and hence even the difference between two unsigned number also can't be negative. So when you subtract an unsigned number from another unsigned it would result in a positive wrapped around number.

Since positive number is greater than 0.

And hence we choose strlen('abc') which is 3.

Hence output is 3.
+1
exactly
0

when you subtract an unsigned number from another unsigned it would result in a positive wrapped around number

why?

+1

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.

0

@Rishav Kumar Singh, What is the answer? isn't it -2?

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

void printlength(char *s, char *t) {
unsigned int c=0;
int len = (strlen(s) - strlen(t));
printf("%d\n", len);
}
void main() {
char *x = "abc";
char *y = "defgh";
printlength(x,y);
}
0
You are printing unsigned integer as signed one

Use %u
0

with  %u you are making it unsigned....

int t=-2;

printf("%d....%u",t,t);

then t is unsigned? NO

come to the question,

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

when you comparing with c, at that moment it is converted as unsigned...

0

when you comparing with c, at that moment it is converted as unsigned..

i know this.

i was answering your question why it is printing -2.

+2 votes

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.

0

If remove unsigned still answer 3

https://rextester.com/OOO61331

0
@Ram Swaroop​​​​​​​

That's because strlen() is an inbuilt function that always returns an unsigned int as the value.

So, (unsigned int - unsigned it > 0?) is the case, which is always true.

Unsigned int - unsigned int can't be signed. So answer is unsigned => positive => greater than 0.
+2 votes
+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);

for this please refer 1st answer value of len is 3.

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)

0 votes
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
+4
Good, but what you just answered showed a different thing - integer constants by default is signed in C.
0 votes
int len = ((strlen(s) - strlen(t)) > c) ? strlen(s) : strlen(t);

Means is strlen(s) - strlen(t) > 0?

If yes, choose stren(s). If no, choose strlen(t).

Mathematically, $3-5 = -2$

So, we choose strlen(t) under normal circumstances.

But, as given in the question, strlen is an unsigned int. Unsigned int $-$ unsigned int can't be signed. Depending on the implementation (out of the scope of this question) the value of $3-5$ would be decided. It is however absolutely sure that the value won't be negative.

Hence, strlen(s) - strlen(t) > 0? Yes.
So, choose strlen(s) which is 3.

0 votes

Hope this helps :)

by
Answer: