I know there must be a duplicate, but I didn't find anything. In C, I see a lot of code examples where the authors only assign values after the declaration of the variable, is there a good reason for doing that?
int main(void)
{
int x; // declare "x"
x = 5; // assign 5 to "x"
return 66;
}
And what's the different between that and just declaring and assigning a value in one line?
int main(void)
{
int x = 5; // declare "x" and assign in the same line
return 66;
}
It's mostly a matter of style these days. In many cases it's less error prone to assign a value to a variable at the point where it's first used, and perhaps as close to its point of first use as possible.
On the other hand, I've certainly seen cases where an algorithm is easier to follow when it isn't dotted with statements that introduce new variables. Collecting up all these statements before the main body of the algorithm may allow the algorithm itself to fit on a single page/screen.
And it seems pointless to assign an initial value to a variable in a construction like this:
int foo;
if (bar == 42)
foo = 1;
else
foo = -1;
Related
Why should one change the value of the main variable and NOT the COPY of the variable.
I have a method
int plusInt(int x){
return ++x;
}
When this function is called, a new stack frame is created, with the copy of x and not the original variable. So this changes this copy's value?
Q: If I want to change the value of the original variable I use a pointer to it and then increase a value right? Eg:
int plusIntPointer(int *x){
return ++*x;
}
But what is the use/why would someone want to change the value of the original variable and not the copy?
So this changes this copy's value?
Exactly, as the function has only the copy, and not the original variable, as a local variable.
If I want to change the value of the original variable I use a pointer to it and then increase a value right?
Right again. The reason you use a pointer is to pass the address of the variable to the function.
But what is the use/why would someone want to change the value of the original variable and not the copy?
The reason is that any changes to the copy will be lost after your function ends and you return to the calling function.
For example, let's assume that you want to use a function in order to swap the values of two variables. Then, you have to change the original values. Your function should be like this :
void swap(int *x, int *y)
{
int temp = *x;
*x = *y;
*y = *temp;
}
and you should call it like this :
swap(&a, &b);
This way, the changes will remain even when you return to the calling function.
If you just change the copies, the variables will not have swapped values when you return to the calling function!!!
Let's say you want to make a function that swaps two variables. Then you need to do this:
void swap(int *a, int *b)
{
int temp = *a;
*a = *b;
*b = *temp;
}
...
void swapwrong(int a, int b) // wont work as intended
{
int temp = a;
a = b;
b = temp;
}
...
int a = 1, b = 2 ;
swap(&a, &b);
printf ("after swap : a=%d b=%d\n", a,b);
swapwrong(&a, &b);
printf ("after swapwrong : a=%d b=%d\n", a,b);
This will print
after swap : a=2 b=1
after swapwrong : a=2 b=1
So this changes this copy's value?
Yes. Only the copy that is local to plusInt
If I want to change the value of the original variable I use a pointer to it and then increase a value right?
Yes. To change a variable in another scope we must preform an indirection. That is achieved by passing the variables address.
But what is the use/why would someone want to change the value of the original variable and not the copy?
The simplest use case one comes across early while learning to program, is when trying to insert a node into the head of a linked list. Your addition function must modify the structure in a calling context.
Well, maybe this is not the simplest. Consider this function
void swap_ints(int l, int r) {
int t = l; l = r; r = t;
}
int main(void) {
int x = 1, y = 2;
swap_ints(x, y);
// Were they swapped?
}
But what is the use/why would someone want to change the value of the
original variable and not the copy?
You can change the copy variable, but this variable will not be available when you code exits the function.
Also, we don't generally call a function just for doing a simple increment. The code
int plusInt(int x){
return ++x;
}
can very well in replace as
x++
instead of calling a function. In optimized mode, compilers may decide to get rid of this function by in-lining the change the code wants to do
We use copy variables in many cases, e.g displaying the value of the variable or in the places where you don't want to reflect any accidental changes
There are many applications of the passing parameters to a function by the pointer. E.g.:
When you pass a parameters to a function, as you mentioned, a space in the stack is allocated and such parameters are copied to this space. This operation may be an expensive, so you may consider to pass such parameters by the pointer. Then the pointer to your data will be passed to your function (i.e., will be copied to the stack). In such case you may consider to put the const with such parameters to prevent an "unexpected" changing of their values (as usually done with the char*).
Sometimes you actually need to change a value of such parameter. Pay your attention to that this will be done "in-place". I.e. there will no a copying operations. In the (modified) your example we may to do something like this:
void increment(int* i)
{
if(i)
++*i;
}
In this example there is no any copying operations (as far of the input parameters, as of the result of the function). Moreover, as you can see, we can to pass the NULL as the value of the i. An algorithm of your function may to handle such the case in a different ways (e.g., to skip this parameter etc).
Using of this method of parameter's passing is suggests itself when you need to change a value of many parameters in one function.
Let's say that any C function has a pointer already declared, but not assigned any value yet. We will int for our examples.
int *ptr;
The goal of the function is not to assign ptr any dynamic memory on the heap, so no malloc call. Instead, we want to have it point to an array of fixed size n. I know I could accomplish this like so:
int arr[n];
ptr = arr;
However, the code could get very messy and hard to read if we need to do this many times in a function, ie, a struct of many pointer fields all need to point to an array of fixed length. Is there a better way to accomplish this in one line? I was thinking of something similar to below, but it looks too ambiguous and uncompilable:
int *ptr;
// Many other things happen in between...
ptr[n];
***EDIT***
Here, the below additional information may help guide some more answers (not saying that the current answers are not fine). In my use case, the pointers are declared in a struct and, in a function, I am assigning the pointers to an array. I want to know if there is a simpler way to accomplish this than in the below code (all pointers to point to fixed-length array):
struct foo {
int* a;
short* b;
char* c;
...
};
void func(void) {
struct foo f;
int n = ...;
int tempArr1[n];
f.a = tempArr1;
short tempArr2[n];
f.b = tempArr2;
char tempArr3[n];
f.c = tempArr3;
...
}
You cannot declare an array and assign it to an existing pointer in a single declaration. However, you can assign an array pointer to a newly declared pointer, like this:
int arr[n], *ptr = arr;
If you insist on staying within a single line, you could use an ugly macro, like this:
#define DECL_ASSIGN_INT_ARRAY(name,size,pointer) int name[(size)]; pointer = name;
The clarity of this one-liner is far lower than that of a two-line version from your post, so I would keep your initial version.
EDIT (in response to the edit of the question)
Another option is to create an unused pointer variable in a declaration, and assign your pointer in an initializer, like this:
void func(void) {
struct foo f;
int n = ...;
int tempArr1[n], *tempPtr1 = f.a = tempArr1;
short tempArr2[n], *tempPtr2 = f.b = tempArr2;
char tempArr3[n], *tempPtr3 = f.c = tempArr3;
...
}
This seems like a clear case where you're in need of some refactoring. Take the similar statements, extract them into a new function (by passing a reference to the struct and the data you want the struct fields to point to) and give this new function a meaningful name.
This is probably more maintainable and readable than some fancy pointer arithmetic shortcut that you'll forget about in a few weeks or months.
The difference between ptr and arr in you example is you can change ptr's value. So I guess you want to move ptr through the array.
So how about this:
int arr[n], id=0;
And you change the value of id and use arr+id as ptr.
I guess the way to do this is to use a macro. Something like (untested)
#define autoptr(name,size) int Arrayname[size]; name = Arrayname;
I'm not clear why this is helping I think it might "look ugly" but will be easier to maintain without the macro. In general, hiding what you are actually doing is a bad thing.
Title pretty much sums this up. How come it's possible that i can assign a locally created Point a (in the function ReadPoint()) into a variable that's in a different scope. Doesn't the locally created Point a gets 'popped' away along with stack of function readPoint() ? What exactly is going on ?
struct Point readPoint(void)
{
struct Point a;
printf("x = ");
scanf("%lf",&b.x);
printf("y = ");
scanf("%lf",&b.y);
return a;
}
int main(int argc, char **argv) {
Point test = readPoint();
printPoint(test);
return 0
}
structs are no different to primitive types in this regard. It's exactly the same principle as:
int foo(void)
{
int x = 5;
return x;
}
int main(void)
{
int y = foo();
printf("%d\n", y);
}
The details of how this is achieved are implementation-dependent. But usually, the return value (whether it's an int or a struct) is placed onto the stack by the called function, and then the caller then can then access that stack location.
The struct is "copied", byte by byte, into test in main...just like returning an int from a function and assigning it to a variable.
This, however, wouldn't happen if you were returning a pointer to the struct and the dereferencing it and assigning (or something similar).
When returning, you'll create a copy of the object (with all members of the struct), but the local variable/object is still destroyed.
This will work unless you try to return a reference or pointer (in these cases your compiler should warn you about this stupid idea). This will work fine, unless you're trying to create a copy of something working with pointers.
In C++ this would include references too.
This is because on return from readPoint() all structure values are copied to another locally defined structure test. Structure a does not survive.
What you're seeing is structure assignment. Almost all modern compilers can handle this.
I want to use the same variable name with a different datatype in C program without casting.
I really wanna do that don't ask why.
So how can I do that ?
And how can I handle the error if this variable doesn't exist while doing prophylactic unsetting ?
You can't. The closest you can get is creating separate scopes and using the same variable name in them:
{
int val;
// do something with 'val'
}
{
double val;
// do something with 'val'
}
If you want the same memory to be referenced with two different types, use a union. Otherwise, know that what follows is a terrible idea.
int foo;
float bar;
#define MY_NAME foo
// use MY_NAME as an int.
#undef MY_NAME
#define MY_NAME bar
// use MY_NAME as a float.
I don't believe this is possible in C. The only way I can imagine doing this would be to write your program such that the two different variables exist in completely different scopes. Such as when you use them in different functions. Other than that, you're stuck with your first variable, pick a different name.
My suggestion -- if you absolutely require then to exist in the same scope -- would be to prefix the name with a type identifying letter, so:
int iVal;
double dVal;
When you define a variable with a name that already exists, the new definition "hides" the old one.
#include <stdio.h>
int main(void) {
int variable = 42;
printf("variable is an int and its value is %d\n", variable);
{
double variable = -0.000000000000003;
printf("variable is a double and its value is %g\n", variable);
}
{
FILE *variable = NULL;
printf("variable is a FILE * and its value is NULL :-)\n");
}
printf("variable is an int again and its value is, again, %d\n", variable);
return 0;
}
You can't change the type of a variable in C. You can use a little preprocessor trickery to get the illusion of what you want. i.e.
int myvar = 10;
// code using myvar as an int
#define myvar _myvar
char *myvar = "...";
// code using myvar as a char*
That being said, I cannot discourage this strongly enough. Don't do it!
# include <stdio.h>
int x = 5;
int main(void)
{
int x = 7;
printf("output = %d\n", x);
}
The above program shows output as 7.
How to print 5 in c?
thanx...
So you're asking how to access a global that's shadowed by a local? You can't in that scope, but something like this should work
# include <stdio.h>
int x = 5;
int get_global_x()
{
return x;
}
int main(void)
{
int x = 7;
printf("output = %d\n", get_global_x());
}
Don't redeclare the x variable in the main function...
In fact, i'm sensing (perhaprs wrongly) that there's another question behind your code, but i'll keep my reaction to it short: if you want to mix global variables and local variables, try to have a convention to distinguish them; for example globals in ALL_CAPS to shout out its scope :)
EDIT: By the way, you should be getting at least a warning from your compiler for redefining a different scope/same name variable. it's really not recommended doing that. Try to always aim for minimum warnings...
You need to give your two variables meaningful names. I'm sure you aren't using x in your real code so do the two vars actually have the same meaning and therefore the same name? If so you could at least do (assuming your ints are counts, but works for all other purposes):
int global_countOfThings = 5;
int main(void)
{
int countOfThings = 7;
printf("output = %d\n", global_countOfThings );
}
But hopefully you'll be able to do something like:
int countOfDucks = 5;
int main(void)
{
int countOfGeese = 7;
printf("output = %d\n", countOfDucks );
}
And of course if you can some how change your code to not use globals you'll be better off in the long run.
You are declaring the same variable in global and local scope. If the same variable is declared in global and local scope, the variable will be treated as local variable. That's the reason you are getting the answer as 7.
Delete the x = 7 line, move the print statement before you print the value or set a different variable to 7 (i.e. write y = 7 instead of x = 7).
u have already declared x to behave as if it is a global variable.to print 5 u can write the pritf statement as:
printf("%d\n",x-2);
The above would print 5.
If you want it 5, why you assign 7? :-) Or you want to access global variable with the same name as local one? Then you might use namespaces... Not sure about C :-)