Issue with scope of variables in C, why a function prints what it's supposed to print - variables

What exactly is going on in this program here? Why does myFunction print 3 for x?
int myFunction(int);
void main(void) /* local variables: x, result in main */
{
int result, x = 2;
result = myFunction(x);
printf("%i", result); /* prints "3" */
printf("%i", x); /* prints "2" */
}
int myFunction (int x)
{
x = x + 1;
printf("%i\n", x); /* prints "3" */
return x;
}

That's because the parameter is a local variable in the function.
When the function is called, there is space allocated on the stack for the parameter, and the value from the variable x is copied into the parameter.
In the function the parameter x is a local varible, separate from the variable x in the calling code. When x is increased in the function, that only happens to the local copy.
When the function ends, the parameter goes away when the stack frame for the function is removed from the stack.

You should read about the differences between pass by value vs. pass by reference in function variables (see here).
In your case, you are passing x by value to myFunction, the function basically gets the value of x (2) and increments it, but never changes the original value of x from your main function.

Related

Please explain me this function inidat

What does that * means before u, what kind of the variable it is, and what will be the output of this function.
Thanks
void inidat (int nx, int ny, float* u)
{
int ix, iy;
for (ix = 0; ix <= nx-1; ix++)
{
for (iy = 0; iy <= ny-1; iy++)
{
*(u+ix*ny+iy) = (float)(ix * (nx - ix - 1) * iy * (ny - iy - 1));
}
}
}
This is a pointer. A pointer is an object whose value refers to another value stored elsewhere in the computer memory using its address. A pointer references a location, and one can get the object stored at that location by "dereferencing" the pointer.
float * x;
cout << *x;
cout << x;
To get the value of the pointer, you do the 2nd line.
To get the location of the pointer you do the 3rd line.
* means that the follow variable is defined or used (to be used, as in this case, it must've been defined before) as a pointer.
As for the output of the function: it's void so it won't return any value but change some in the last line, I would need the context of the function to see what it's actually doing.

pointer to function syntax and usage

I apologize if this was asked many times.
I'm trying to understand why both of this works fine without any warnings or other visible issues (in Xcode):
int testFunctionAcceptingIntPointer(int * p) {
return *p = *p +5;
}
void test() {
int testY = 7;
typedef int (*MyPointerToFunction)(int*);
// Both this (simply a function name):
MyPointerToFunction functionPointer = testFunctionAcceptingIntPointer;
// And this works (pointer to function):
MyPointerToFunction functionPointer = &testFunctionAcceptingIntPointer;
int y = functionPointer(&testY);
}
The code works fine without warnings both ways because a function designator is converted to a function pointer
MyPointerToFunction functionPointer = testFunctionAcceptingIntPointer;
unless it is the operand of the address operator
MyPointerToFunction functionPointer = &testFunctionAcceptingIntPointer;
(or sizeof and _Alignof).
In the first assignment, you don't use &, so the automatic conversion is done, resulting in a function pointer of appropriate type, in the second, you explicitly take the address, resulting in a function pointer of the appropriate type.

Why can't you assign and call a block at the same time?

The following code compiles:
^{}();
And this compiles:
void (^x)();
(x = ^{})();
But this doesn't:
(void (^x)() = ^{})();
The error I get is Expected ')'. Is this a bug with llvm or something? It's totally holding me back from pretending Objective-C is JavaScript.
This wouldn't make sense in a C-like language. To see why, let's build the statement from the ground up.
First, we'll use your working declaration for x:
void (^x)();
Now let's initialize it in the same statement:
void (^x)() = ^{};
So far so good - x has been initialized with the correct block. So let's invoke x now. But where will the () go? Naturally, we need to place the () immediately after a block-valued expression. However, in C, declarations are statements, not expressions so
(void (^x)() = ^{})();
doesn't make sense. The only place the () can go is after the ^{}:
void (^x)() = ^{}();
But ^{}() has type void, not type void (^)().
To sum up: you can't declare a block variable and invoke it at the same time. you'll have to either declare and initialize the variable, and then call it
void (^x)() = ^{};
x();
or declare it and then assign and call it
void (^x)();
(x = ^{})();
or just separate all three:
void (^x)();
x = ^{};
x();
As a concluding thought, let's say it was desirable to declare and invoke blocks at the same time. If we decided to allow code like (void (^x)() = ^{})();, then for the sake of consistency, we would have to also allow code such as ++(void x = 4); or (void x = 1) + (void y = 2);. I hope you'll agree that these just look strange in C.
As an analogy, consider:
This compiles:
if (42) { }
And this compiles:
int x;
if (x = 42) { }
But this doesn't:
if (int x = 42) { }

Confusion on passing in pointers to functions

I'm reading a book to learn Objective-C and this program is suppose to show key concepts in dealing with pointers, and I'm really lost.
Is there some kind of conversion happening in the function's arguments that turn p1, p2, &il, and &i2 to the value (*) of a pointer? Like p1 turns into *p1?
I thought a copy of the variable was passed into the function instead of the actual variable, so why was the value of the passed in variable changed after the function?
Also why am I getting a warning on the 3rd line that says: No previous prototype for function 'exchangeValues'?
Thank you!!
#import <Foundation/Foundation.h>
void exchangeValues (int *pint1, int *pint2) {
int temp;
temp = *pint1;
*pint1 = *pint2;
*pint2 = temp;
}
int main (int argc, char *argv[]) {
#autoreleasepool {
void exchangeValues (int *pint1, int *pint2);
int il = -5, i2 = 66, *p1 = &il, *p2 = &i2;
NSLog(#"il = %i, i2 = %i", il, i2);
exchangeValues(p1, p2);
NSLog(#"il = %i, i2 = %i", il, i2);
exchangeValues(&il, &i2);
NSLog(#"il = %i, i2 = %i", il, i2);
}
return 0;
}
Output:
2012-08-02 11:13:38.569 Test[381:707] il = -5, i2 = 66
2012-08-02 11:13:38.571 Test[381:707] il = 66, i2 = -5
2012-08-02 11:13:38.572 Test[381:707] il = -5, i2 = 66
I would say that's a complex example if you are being taught about pointers!
Is there some kind of conversion happening in the function's arguments
that turn p1, p2, &il, and &i2 to the value (*) of a pointer? Like p1
turns into *p1?
p1 and p2 are declared as int * (pointer to int) and are initialised with the address of i1 and i2 (using the & operator).
I thought a copy of the variable was passed into the function instead
of the actual variable, so why was the value of the passed in variable
changed after the function?
A copy of the variable is passed to the function, however in this case the variable of type int * (pointer to int). The reason the value is changing is because the exchangeValues() function is dereferencing those pointers and swapping the values. This is the only way (in C/Objective-C) a function can modify a variable outside of its own scope, other than the variable being assigned as the return value from a function.
Also why am I getting a warning on the 3rd line that says: No previous
prototype for function 'exchangeValues'?
You seem to have typed it in wrong; remove the line below #autoreleasepool:
#autoreleasepool {
void exchangeValues (int *pint1, int *pint2); <-- delete this line
If you pass a pointer into the function, it indeed passes a copy of that pointer- but it still refers to the same address in memory. So de-referencing that pointer will still point to a variable that's outside of the function scope.
I thought a copy of the variable was passed into the function instead of the actual variable, so why was the value of the passed in variable changed after the function?
A copy of the pointer is passed to the function here. So what the function has points to the memory locations the variables l1 and l2 are stored at. So
void exchangeValues (int *pint1, int *pint2) {
int temp;
temp = *pint1; // store the value that pint1 points to in temp
*pint1 = *pint2; // store the value pint2 points to where pint1 points to
*pint2 = temp; // store the value saved in temp where pint2 points to
}
its a little confusing how the variables have been declared and initialised all in a row like that but basically you have:
i1 is an int set to -5
p1 is a pointer to an int set to the address of i1
same goes for i2 and p2
No conversion is taking place. You're effectively 'swapping' the values that those pointers point to in the function.
Pointers are confusing things but stick with it and it will become clear with enough parctice and example code like this...

Redefine / resize C array in Objective C?

I have a C array in Objective C defined as follows:
id keysArray;
Then in an if block, i would like to redefine the array based on a condition:
if (somethingIsTrue){
id keysArray[4][3];
}
else {
id keysArray[6][1];
}
Then outside of the if block, when i access the array, i get errors saying the keysArray does not exist.
Thanks.
That's because when you leave the scope of the if, all local variables defined within that scope are destroyed. If you want to do this, you will have to use dynamic allocation. I don't know the Objective C way of doing things, but in regular C you shall use malloc.
In C, once created, arrays cannot change size. For that you need pointers and malloc() and friends.
In C99 there's a new functionality called "variable length array" (VLA) which allows you to use arrays with lengths defined at run time (but fixed for the duration of the object)
while (1) {
/* C99 only */
int rows = 1 + rand() % 10; /* 1 to 10 */
int cols = 1 + rand() % 10; /* 1 to 10 */
{
int array[rows][cols];
/* use array, different sizes every time through the loop */
}
}