-1

Output of the following program is : 3 1 3

int main()
{
    int a = 0, b = 1, c = 3;
    *((a) ? &b : &a) = a ? b : c; // Couldn't understand expression
    printf("%d %d %d \n", a, b, c);
    return 0;
}

How ternary operator is working here for this output?

Grijesh Chauhan
  • 57,103
  • 20
  • 141
  • 208
dcoder11
  • 31
  • 4
  • 1
    Which part is unclear? `a` is `0` so it should be obvious which option is chosen in both cases. – JJJ Aug 13 '13 at 15:18
  • 4
    Tell us what you think the output should be along with your reasoning and we will tell you if you are right or wrong. – Colin D Aug 13 '13 at 15:19
  • I think the question is about the references being used in the first ternary operator. It is a bit confusing. – Reinstate Monica -- notmaynard Aug 13 '13 at 15:20
  • 2
    Replace the ternary operator by an `if ... else` ? – nouney Aug 13 '13 at 15:21
  • @iamnotmaynard especially confusing since they're not references; they're variable addresses, of which one (being returned from the ternary condition) is being *dereferenced*. Methinks you're on to something, however. Perhaps the OP just doesn't do pointers. – WhozCraig Aug 13 '13 at 15:29
  • @WhozCraig Stupid question here: what is the difference between a reference and a variable address? (I haven't used C in a while; I mostly do Java, which doesn't really do pointers, except when it kind of does.) – Reinstate Monica -- notmaynard Aug 13 '13 at 15:38
  • @iamnotmaynard Addresses are the fundamental "values" of pointers, where-as references, (the C++ term) a different, more restrictive (and thats a good thing) beast. See [this discussion](http://stackoverflow.com/questions/57483/what-are-the-differences-between-pointer-variable-and-reference-variable-in-c). – WhozCraig Aug 13 '13 at 15:40

3 Answers3

5
 *( (a) ? &b : &a) =     a ? b : c ;
     ^                   ^
     = 0                 = 0
     ==false             ==false

so the above expression:

 *( &a) =  c ;

that is:

     a =  c ;

because c = 3;, so it give:

     a =  3 ;   

b is 1 and c is 3 in your declaration(remains unchanged).

Grijesh Chauhan
  • 57,103
  • 20
  • 141
  • 208
0

My C is a little weak, so if I'm off-base here, someone let me know.

Assuming you're talking about the expression *((a) ? &b : &a) (and that you know how the ternary operator works generally), here's how it breaks down:

The condition (a) is evaluated: when using an int in a boolean, 0 evaluates to false, while positive (or non-zero?) values evaluate to true — in this case, a == 0 is false.

The ternary then returns the value &b if true and &a if false (in this case it's false, so it returns &a).

The value thus returned is a reference to a variable; the asterisk before the surrounding parentheses dereferences this reference, so the expression *((a) ? &b : &a) evaluates to the variable — but not the value of — a (if a where not 0, the expression would evaluate to b).

That line then assigns to this variable (in this case a) the value of the second ternary expression, which I assume you can figure out.

The final effect is that it assigns the value of c to the variable a, which explains the output.

0

Note that the ternary conditional operator has higher precedence than the assignment operator. The ternary conditional has the form:

condition ? true-result : false-result

If condition is true, the result is true-result, otherwise the result is false-result. The operator is short-circuiting in the sense that only one of the results is ever evaluated.

This operator can be used for conditional assignment. For example:

int days_of_year = is_leap_year ? 366 : 365;

The result of the ternary conditional is an r-value. This means that the result is a value that cannot be the target of an assignment. However, there is a trick that can be used to use the ternary conditional with pointers and dereference so as to get the behavior of conditionally assigning to one variable or another.

int x;
int y;
*(need_x ? &x : &y) = 0;

While the result of a ternary condition is an r-value, the result of a dereference is an l-value. This means the result of the dereference can be used as the target of an assignment.

Your code uses both of these ideas in combination.

jxh
  • 69,070
  • 8
  • 110
  • 193