I thought I am allowed to declare variables in the way I did.
int x = y = 10;
However, my compiler says it is a use of undeclared identifier 'y'
Am I not allowed to declare such a way?
The definition above parses as:
int x = (y = 10);
This defines x and initializes it to the result of the expression y=10. This expression assigns the value 10 to y and evaluates to 10. So here y is expected to already exist.
Multiple variables in a definition are separated commas, and each variable may have an initializer. So you can do this:
int x = 10, y = 10;
Or even this:
int x = 10, y = x;
The latter works because x exists and has been initialized at the time y is defined.
You can try this method below. It's technically two lines but you must first define the variables before assigning values to them in this case.
int x, y;
x = y = 10;
Related
I have to analyze what some code in C does, and I have a doubt about what happens in a certain line. The code is
#define PRINTX printf("%d\n", x)
void problem() {
int x = 2, y, z;
x *= 3 + 2; PRINTX;
x *= y = z = 4; PRINTX;
x = y == z; PRINTX;
x == (y = z); PRINTX; // This line is the problem
}
This code snippet prints the resulting numbers:
10
40
1
1 // This result **
the problem is that I'm still trying to figure out why does the last line prints out x = 1, when the operation is x == (y = z). I'm having trouble finding out what that 1 means and the precedence of the operations. Hope someone can help me! :)
Nothing in the last statement changes the value of x, so its value remains unchanged.
Parens were used to override precedence, forcing the = to be the operand of the ==.
An operator's operands must necessarily be evaluated before the operator itself, so we know the following:
y is evaluated at some point before the =.
z is evaluated at some point before the =.
x is evaluated at some point before the ==.
= is evaluated at some point before ==.
That's it. All of these are valid orders:
z y = x ==
y z = x ==
x y z = ==
etc.
But whenever x, y and z are evaluated, we can count on the following happening:
= assigns the value of z (currently 4) to y and returns it.
== compares the value of x (currently 1) with the value returned by = (4). Since they're different, == returns 0 (which isn't used by anything).
As you see, nothing changed x, so it still has the value it previously had (1).
In the last statement, nothing is changing the value of x. We are testing if x equals something, but we aren't changing it's value.
So it continues having the same value as it had in the previous statement, in particular, a value of 1.
the reason is because the == operator checks if the 2 numbers are equal, and returns 1 if equal and 0 if not equal that is why it returns one you can check by making x= 1 and y=2 and using the == operator between them
The comparison result of x and assignment of y with (y = z) is discarded. Last line could have dropped the compare: y = z; PRINTX;.
The assignment is not subsequently used either, so the line could have been PRINTX;.
I'm first year student in Software Engineering and in my last task I used (chain assignment) multiple assignment of values.
The lecturer claims that it is illegal to assign values in this way.
X = Y = Z;
(The three variables are declared in the beginning of the function).
I would be happy if you can explain to me if the assign is right action and if what the teacher claims is right.
It depends on whether all of the objects were correctly declared and Z was initialized or assigned with an appropriate value before this statement or not.
You can even assign values of objects of different types due to implicit casting, but the object which is getting assigned needs to be capable of holding the value of the object which is assigned to this one.
If Z was initialized or assigned before and all objects were correct declared, then:
X = Y = Z;
is completely correct and legal as it assigns the value held in Z to Y and X - the assignment takes place from right to left.
For example:
int X,Y,Z; // All objects are declared.
Z = 24; // `Z` is assigned with the integer value 24.
X = Y = Z; // `X` and `Y` get assigned by 24 which is the value in `Z`.
Else if Z has an indeterminate value (f.e. if it was not declared with the extern or static keyword or declared at global scope) and you would assign this value to Y and X with that statement.
Although the assignment itself would be even then not illegal, if you would use one of the assigned objects the program would give undefined results/output.
Speaking for the multiple assignments only, there is nothing illegal about it, you could even use:
O = P = Q = R = S = T = U = V = W = X = Y = Z;
if all objects used were correctly declared before and Z has an determined value.
The lecturer claims that it is illegal to assign values in this way.
If it is possible, I would ask her/him or your teacher, what s/he meant with that. Maybe there is something specific to your course you should care about.
Almost every expression has a value.
An assignment is an expression with value.
The value of the expression i = 42 is 42.
Assignment associates right to left, so the expression a = b = c is the same as a = (b = c).
So
int i;
double d;
char c;
c = i = d = 42;
Converts 42 to double and assigns to d. The value of this assignment is 42.0.
Then this value is converted to int and assigned to i. Value of this assignment is 42.
Lastly the int value is converted to char and assigned to c.
c = (i = (d = 42));
It's legal, for example:
float x;
int y;
float z = 3.5;
x = y = z;
it's similar to y = z; x = y;. So in this case, z = 3.5, y = 3 and x = 3;
But it will give the warning if you did not initialize the value of z.
int x,y, z;
x = 0;
y = 1;
//z = 2;
x = y = z;
Together with right-associativity of evaluation, and assuming non-volatile a, b, and c, it means that a = b = c is equivalent to a = (b = c), and again equivalent to b = c; a = b
Assigning values to multiple variables in a single line is perfectly alright and is allowed by C programming language.
However, the use of this style is usually discouraged because it may cause undesirable side-effects in some cases.
The expectation of Mathematical equation X = Y = Z may be:
Y = Z and X = Z (I.E., Assign the value of Z to both X and Y)
But C language treats the multiple assignments like a chain, like this:
In C, "X = Y = Z" means that the value of Z must be first assigned to Y, and then the value of Y must be assigned to X.
Here is a sample program to see how the multiple assignments in single line work:
#include <stdio.h>
int main() {
int n;
int X, Y, Z;
printf("Enter an integer: ");
scanf("%d", &n);
printf("You entered: %d\n", n);
printf("Performing multiple assignments:\n X = Y = Z = n++ \n");
X = Y = Z = n++;
printf("n = %d\n", n);
printf("X = %d \n", X);
printf("Y = %d \n", Y);
printf("Z = %d \n", Z);
return 0;
}
Output:
Enter an integer: 100
You entered: 100
Performing multiple assignments:
X = Y = Z = n++
n = 101
X = 100
Y = 100
Z = 100
Points to note in the above example:
The line X = Y = Z = n++ got processed like this:
Step 1: Assign the value of n (100) to Z
Step 2: Increment the value of n (n becomes 101)
Step 3: Assign the value of Z to Y (Y becomes 100)
Step 4: Assign the value of Y to X (X becomes 100)
Conclusion:
'Multiple assignments in single line' is a supported style. It has its benefits.
However, if the programmer is not aware of the sequence of operations involved in the multiple assignments statement, then it can lead to inconsistency between the expectation of the person who reads the program and the actual result of the execution.
To avoid this scenario, the multiple assignments are discouraged.
There's nothing illegal about it, provided each variable is only modified once. For example, the following all have well-defined behavior:
x = y = z;
x = y = z = x + 1;
x = y++ + --z;
x += (y = (z += 1)) - 6;
But the following have undefined behavior, and should be avoided:
x = y = x = z;
x = x++;
x = y++ + y++
x = func(y++, y++);
I have a function to evaluate and I want to graph it point by point. But the function only gives me a value and not the set of evaluated values.
rho = 0.999;
n = -10:1:10;
x = (rho.^(n))*(1 - rho)
y = 1 - (rho.^(n + 1))
Pb = x/y
plot(n, Pb)
x is a 1x21 double array just like y but my evaluated function Pb is a single value, not a set of evaluated values. Therefore I do not get my graph
What is the problem with the code?
I'm assuming you want to divide each element of x by its corresponding y? Fix the line
Pb = x./ y;
int *p;
int x;
int k;
x = 30;
k = x;
p = &x;
After these statements, which of the following statements will the value of x to 60? My answer is 1. But I'm not sure if I am correct, because seem like other answer is correct too. Please gives some explanation.
1. k = 60;
2. *k = 60;
3. p = 60;
4. *p = 60;
Here is an explanation:
int *p; //declares a pointer to an integer
int x; //declares an integer called x
int k; //declares an integer called k
//at this point all values are uninitialized and could contain anything
x = 30; //the numerical value 30 is assigned to x
k = x; //the contents of x(30) is assigned to k
p = &x; //the address of int x is stored in p
//now all values have valid and reliable values
Now let me explain what each line you described does:
k = 60; //assigns value 60 to variable k
*k = 60; //attempts to dereference k which is a non pointer type (compile time error)
p = 60; //attempts to assign the value 60 to a pointer p this is NOT what you want
*p = 60; //dereferences pointer p(which points to x) and sets the value 60 to it
the last line has the same effect as x=60; so it is the correct answer.
k=60; will not affect the content of x, because x and k are different variables they each have their own separate memory. k=x; will simply copy the contents of x into k, it will not make the variables aliases of each other.
You can simply compile it and run it in a debugger via single step to see how it works.
The answer is not 1. You're close, answers 2 and 3 don't make sense.
p = &x
p points to the memory address of x so setting
p = 60
would be setting its address to 60 which is not what you want.
k = x;
Changing k will not change x because k doesn't store the memory of x, it has instead copied the value of x.
*p = 60
The value that p is pointing to equals 60, in this case p is pointing to the address of x
So when ever the value at the address of x changes, *p changes or vice versa.
The key point is *p is pointing the value at the memory address of x, so changing *p changes x
The answer is 4.
#define div_ac_power(y,x) *y/x
Shall y be an address? As far as I understand it returns the result of division between a pointer (y) and whatever object is x.
As far as I understand it returns the result of division between a pointer (y) and whatever object is x.
That is probably the intention.
The macro needs more parenthesis to secure it from misuse.
Consider the following cases:
Case 1. Compound parameter:
result= div_ac_power(y,a+b);
which is expanded to:
result = *y/a+b; // This equals (*y/a)+b because of operator precedence.
Case 2. Fooling around:
result= a div_ac_power(y,b); // Note the lack of operator between a and macro
which is expanded to:
result= a*y/b; // This may well be a valid expression depending on the types of a, b, y.
To fix it, you could add parenthesis:
#define div_ac_power(y,x) (*(y)/(x))
Dereference the value pointed-to by y pointer
Divide this value by x value
Same as:
int *y, x; // init them
int z = *y;
int res = z / x;