When should I use a pointer to assign to an int? - c

Why and when should I use one method or another? I am trying to learn more about pointers, but I cannot understand this kind of usage scenario.
int i = 12;
i += 1; // 13
i = 55; // 55
int x = 6;
int * y = &x;
*y += 1; // 7
*y = 91; // 91
I have researched this question already but could not find an answer, thus the post on SO. I am not asking the difference between what they do, I understand their effect on memory. I do not understand which should be used in the style of scenario above. The title was updated to reflect this misunderstanding.

You'd use a pointer whenever access to an object needs to be done indirectly, such as:
when an object declared outside a function needs to be modified within a function (or when an array is passed to a function)
when an object is dynamically allocated with malloc or other allocation functions
when you're working with data structures (e.g. linked lists, tables, trees)

int i = 12;
i += 1; // 13
i = 55; // 55
In your example, you are creating a temporary integer variable i and storing the value 12 in it. You are then taking the value already stored in i (12) and adding 1 to it.
i += 1; is the same as i = i + 1; in your case i = i + 1 is equivalent to this math:
i = 12 + 1
You are then throwing away the value that you have just stored in i and replacing it with 55. You have overwritten the data stored in the temporary variable i.
int x = 6;
int * y = &x;
*y += 1; // 7
*y = 91; // 91
Now, in the case of x and y, you x is a temporary integer variable just like i above.
By saying int * y = [something]; however, you are declaring a temporary integer pointer to the memory location of some integer. Usually the memory address of some variable that has already been created. Setting y equal to the address of x sets the thing that the pointer is pointing to the location in memory of x. Under this setup, dereferencing y (*y) will yield the value of x, not the address of it. If you print out y, you will print the address of x. If you print out *y, you will print out the value of x. *y += 1 yields the value of x + 1. Setting *y to 91 resets the value of x, in the same way, that you have done above with i and 55.
Allow me to demonstrate the usefulness of this pointer through an example.
Let's say you had 4 integer pointers all set to point to the address of x (&x). Changing the value of any one of those pointers after dereferencing them (*ptr) will change the value stored in x and thus the value pointed to by each of the other 3 pointers you have initialized to the address of x.
By contrast, let's say you have 4 variables (int m, int n, int j, int k) all set equal to 4. When you increment k by 1, it will not change the value stored in m, n or j. It will only change k.

I know my answer will raise many eyebrows here but I can relate the question you asked here, so replying.
To keep your programming simple you can avoid the use of pointers as long as possible. Most of the programs you will write initially will not require pointers at all.
However, as you start writing complicated programs where you'll also need to keep the execution time as minimal as possible, you may want to use pointers.
Apart from time constraints, there are many other places where pointers will be used e.g. when you want to pass/return structures to/from a function. Because passing/returning structures as the value will put a load on the stack.
However, pointers are complicated and you may want to avoid them for writing simple programs if you really don't have any limitation of memory/time in your system.
You can anyways google (or read some books) about pointers for more information.

the basic difference between * and & as follows:
* - indicates the value of the operator
and
& - indicate the address of the operator

Related

What is the difference between ways to point in arrays?

Assume that I define x as array like this: int x[30]={2,4,8,9,6,3,5,4,7,8,9,6,3,2,} and A as a pointer to an int like this: int *A.
Now I want to know what the difference is between these:
int *A=x[5]
int *A ; A=&x[5]
int *A=x+5
int *A ; *A=x+5
int *A ; A=*(x+5)
Why do number 1, 4 and 5 give an error?
Number 4 gives an error although number 3 doesn't. Why are these not equal?
In number 1, you're creating a variable A which is a pointer to an int, and x[5] is an int, not a pointer. So you're giving a pointer an int value, which produces an error.
In number 2, you create a pointer to an int and then make it point to the variable x[5], since &x[5] is the address of x[5]. That will compile just fine and the way you wrote it won't produce any error, however creating a pointer without any initial value is not recommended. When you create A without initializing it, it will take the value that was already in the memory which can be any value. Therefore, if you use the variable A before giving it an error, your program will crash. Instead, it's recommended to do:
int *A = NULL;
A = &x[5];
or simply:
int *A= &x[5];
In number 3, you're creating a pointer to an int and you're assigning it the value x + 5. This is OK since x is in fact a pointer to x[0] (x and &x[0] do exactly the same thing). So x + 5 is a pointer to the value that is 5 memory spaces after x[0], which is x[5]. In fact, when the compiler sees x[5], it converts it to *(x + 5).
In number 4, A is a pointer to an int, so *A is the value which A is pointing to, which is an int. In you're code, *A = x + 5 is wrong for two reasons: For the first reason, the code won't compile since x + 5 is a pointer and *A is an int, so you're assigning a pointer value to an int, which isn't valid. But there is another error in there. Imaging it compiled for some reason. Then, at runtime, what it does, is that it takes the memory space that A is pointing to and gives it the value x + 5. The problem is that A isn't initialized so it's very likely that A points to a variable used by another program. To prevent this from doing any damage, your OS will make the program crash. If you're "lucky", A will point to a variable in your program so it will assign a new value to a variable in your program without you knowing which variable it is, so your program will continue running but won't work correctly.
In number 5, A is a pointer to an int and you're assigning it the value *(x + 5). As I explained earlier, *(x + 5) is exactly the same thing as x[5], which is an int. So you're assigning an int value to a pointer, which is not valid. Note that if for some reason you want to assign an int value to a pointer, you could do A = (int*)(*(x + 5)), which would compile properly (but the program would probably crash at runtime). Then A would be a pointer pointing to the memory space 3. In the same way, you can also do x[5] = (int)A, which stores the address of the variable that A is pointing to as an int in x[5]. However, I've never seen any situation where these kinds of things would be useful in practice.

How do I use pointers? in C

Im fairly new to C programming and I am confused as to how pointers work. How do you use ONLY pointers to copy values for example ... use only pointers to copy the value in x into y.
#include <stdio.h>
int main (void)
{
int x,y;
int *ptr1;
ptr1 = &x;
printf("Input a number: \n");
scanf("%d",&x);
y = ptr1;
printf("Y : %d \n",y);
return 0;
}
It is quite simple. & returns the address of a variable. So when you do:
ptr1 = &x;
ptr1 is pointing to x, or holding variable x's address.
Now lets say you want to copy the value from the variable ptr1 is pointing to. You need to use *. When you write
y = ptr1;
the value of ptr1 is in y, not the value ptr1 was pointing to. To put the value of the variable, ptr1 is pointing to, use *:
y = *ptr1;
This will put the value of the variable ptr1 was pointing to in y, or in simple terms, put the value of x in y. This is because ptr1 is pointing to x.
To solve simple issues like this next time, enable all warnings and errors of your compiler, during compilation.
If you're using gcc, use -Wall and -Wextra. -Wall will enable all warnings and -Wextra will turn all warnings into errors, confirming that you do not ignore the warnings.
What's a pointer??
A pointer is a special primitive-type in C. As well as the int type stored decimals, a pointer stored memory address.
How to create pointers
For all types and user-types (i.e. structures, unions) you must do:
Type * pointer_name;
int * pointer_to_int;
MyStruct * pointer_to_myStruct;
How to assing pointers
As I said, i pointer stored memory address, so the & operator returns the memory address of a variable.
int a = 26;
int *pointer1 = &a, *pointer2, *pointer3; // pointer1 points to a
pointer2 = &a; // pointer2 points to a
pointer3 = pointer2; // pointer3 points to the memory address that pointer2 too points, so pointer3 points to a :)
How to use a pointer value
If you want to access to the value of a pointer you must to use the * operator:
int y = *pointer1; // Ok, y = a. So y = 25 ;)
int y = pointer1; // Error, y can't store memory address.
Editing value of a variable points by a pointer
To change the value of a variable through a pointer, first, you must to access to the value and then change it.
*pointer1++; // Ok, a = 27;
*pointer1 = 12; // Ok, a = 12;
pointer1 = 12; // Noo, pointer1 points to the memory address 12. It's a problem and maybe it does crush your program.
pointer1++; // Only when you use pointer and arrays ;).
Long Winded Explanation of Pointers
When explaining what pointers are to people who already know how to program, I find that it's really easy to introduce them using array terminology.
Below all abstraction, your computer's memory is really just a big array, which we will call mem. mem[0] is the first byte in memory, mem[1] is the second, and so forth.
When your program is running, almost all variables are stored in memory somewhere. The way variables are seen in code is pretty simple. Your CPU knows a number which is an index in mem (which I'll call base) where your program's data is, and the actual code just refers to variables using base and an offset.
For a hypothetical bit of code, let's look at this:
byte foo(byte a, byte b){
byte c = a + b;
return c;
}
A naive but good example of what this actually ends up looking like after compiling is something along the lines of:
Move base to make room for three new bytes
Set mem[base+0] (variable a) to the value of a
Set mem[base+1] (variable b) to the value of b
Set mem[base+2] (variable c) to the sum mem[base+0] + mem[base+1]
Set the return value to mem[base+2]
Move base back to where it was before calling the function
The exact details of what happens is platform and convention specific, but will generally look like that without any optimizations.
As the example illustrates, the notion of a b and c being special entities kind of goes out the window. The compiler calculates what offset to give the variables when generating relevant code, but the end result just deals with base and hard-coded offsets.
What is a pointer?
A pointer is just a fancy way to refer to an index within the mem array. In fact, a pointer is really just a number. That's all it is; C just gives you some syntax to make it a little more obvious that it's supposed to be an index in the mem array rather than some arbitrary number.
What a does referencing and dereferencing mean?
When you reference a variable (like &var) the compiler retrieves the offset it calculated for the variable, and then emits some code that roughly means "Return the sum of base and the variable's offset"
Here's another bit of code:
void foo(byte a){
byte bar = a;
byte *ptr = &bar;
}
(Yes, it doesn't do anything, but it's for illustration of basic concepts)
This roughly translates to:
Move base to make room for two bytes and a pointer
Set mem[base+0] (variable a) to the value of a
Set mem[base+1] (variable bar) to the value of mem[base+0]
Set mem[base+2] (variable ptr) to the value of base+1 (since 1 was the offset used for bar)
Move base back to where it had been earlier
In this example you can see that when you reference a variable, the compiler just uses the memory index as the value, rather than the value found in mem at that index.
Now, when you dereference a pointer (like *ptr) the compiler uses the value stored in the pointer as the index in mem. Example:
void foo(byte* a){
byte value = *a;
}
Explanation:
Move base to make room for a pointer and a byte
Set mem[base+0] (variable a) to the value of a
Set mem[base+1] (variable value) to mem[mem[base+0]]
Move base back to where it started
In this example, the compiler uses the value in memory where the index of that value is specified by another value in memory. This can go as deep as you want, but usually only ever goes one or two levels deep.
A few notes
Since referenced variables are really just numbers, you can't reference a reference or assign a value to a reference, since base+offset is the value we get from the first reference, which is not stored in memory, and thus we cannot get the location where that is stored in memory. (&var = value; and &&var are illegal statements). However, you can dereference a reference, but that just puts you back where you started (*&var is legal).
On the flipside, since a dereferenced variable is a value in memory, you can reference a dereferenced value, dereference a dereferenced value, and assign data to a dereferenced variable. (*var = value;, &*var, and **var are all legal statements.)
Also, not all types are one byte large, but I simplified the examples to make it a bit more easy to grasp. In reality, a pointer would occupy several bytes in memory on most machines, but I kept it at one byte to avoid confusing the issue. The general principle is the same.
Summed up
Memory is just a big array I'm calling mem.
Each variable is stored in memory at a location I'm calling varlocation which is specified by the compiler for every variable.
When the computer refers to a variable normally, it ends up looking like mem[varlocation] in the end code.
When you reference the variable, you just get the numerical value of varlocation in the end code.
When you dereference the variable, you get the value of mem[mem[varlocation]] in the code.
tl;dr - To actually answer the question...
//Your variables x and y and ptr
int x, y;
int *ptr;
//Store the location of x (x_location) in the ptr variable
ptr = &x; //Roughly: mem[ptr_location] = x_location;
//Initialize your x value with scanf
//Notice scanf takes the location of (a.k.a. pointer to) x to know where
//to put the value in memory
scanf("%d", &x);
y = *ptr; //Roughly: mem[y_location] = mem[mem[ptr_location]]
//Since 'mem[ptr_location]' was set to the value 'x_location',
//then that line turns into 'mem[y_location] = mem[x_location]'
//which is the same thing as 'y = x;'
Overall, you just missed the star to dereference the variable, as others have already pointed out.
Simply change y = ptr1; to y = *ptr1;.
This is because ptr1 is a pointer to x, and to get the value of x, you have to dereference ptr1 by adding a leading *.

What is the difference between "*x = 1" and "x = 1" in C?

I'm very new to C. I come from a Java background, and I'm having a hard time understanding pointers. My understanding of what *x = 1 is take the memory address of x and assign it to 1, where as x = 1 means assign the variable x to the value 1.
Am I correct?
Well, as written you have it completely backwards, since you're saying assign x to the value 1 etc.
x=1 means store the value 1 to the variable x.
*x=1 means store the value 1 at the memory address x points to.
*x = 1;
means that x contains a memory address, assign 1 to that memory address.
x = 1;
means assign 1 to the variable x.
x = VARIABLE
*x = POINTER TO ADDRESS
By saying x=1 means you are directly assigning the value 1 into the x. Where as *x=1 has a bit different approach.
Say, int y = 10 and x is a pointer which is pointing to the address of y by defining int *x = &y. After declaration of *x, through out the program, *x will be treated as the value at the address of y. So, when *x=1 is used, the the value at the address of y, which was 10 earlier, will be changed to 1 now. Thus, y=1 and *x=1 are internally doing same thing.
You can follow this link for detailed understanding in simpler way about C pointers.

Pointers in c programming

I am new to the pointer concepts.. i dont understand the following program.. please tell about the logic of this program..
function (int *p,int *q){
return(*p = (*p + *q) - (*q = *p));
}
int main(){
int y = 15, z = 25;
function(&y, &z);
printf("%d\t%d", z, y);
}
This program invokes undefined behavior. It both modifies and uses the value of *q without a sequence point between.
C99 standard, Section 6.5, paragraph 2:
Between the previous and next sequence point an object shall have its stored value
modified at most once by the evaluation of an expression. Furthermore, the prior value
shall be read only to determine the value to be stored.
*q is read in the sub-expression (*p + *q), and this is not done to determine the value to store in the sub-expression (*q = *p).
The intent appears to be to swap the two values pointed to, but a completely reasonable alternate interpretation also exists: evaluate (*q = *p) first, then (*p + *q) (which would equal *p + *p thanks to the assignment). This would result in *p being assigned *p + *p - *p, or just *p. As a result, z would be assigned the value of y (15), while y would remain 15.
I must emphasize that because this is undefined, your compiler can do pretty much whatever it wants, not just limited to this interpretation or swapping the two.
Pointer means you pass the address of the variables instead of the value.
You can then dereference(get the value pointed to by this address) and perform operations using that value.
If you pass a variable by value, that is without using &, a new copy will be created inside the function. Any changes done, will not be visible outside the function. If you pass pointers, then manipulations done to the content of the pointer will be visible outside the function.
On last note, pointers are complex to understand for new programmers. You better read tutorials and spend some time thinking about how things are working.
This is example of function where you pass by reference that is you pass the location of actual variable instead of making a copy of it and passing.so in you function p is basically pointing to y which is 15 and q is pointing to z=25 .It should be easy from there on to find the answer. *p= (15+25)-(15) *q=15.So y=25 z=15 .
First of all you have to know about the pointer...
Pointer is a variable that contain memory address of another variable...
In above program...you have declared 2 variables y and z... and you have created a function
namely function(&y,&z).... means ...it sends the reference (memory address) of y and z to the funcion...function(*p,*q)
so *p contain 15 and *q contain 25...
*p=(*p+*q) means y= 15+25 which is 40....
Variable, like y and z in your program, have ranges. They exist only in a limited logical space. For instance, y and z only "exists" in main ; that's why they're called "local variable". Would you write :
int x,y;
void main
{
// Stuff
}
x and y would be global variables, that any function in this file could access. Since global variable make things harder to debug, when you need to access variable declared in a function, you can use pointer (it's only one of the uses of pointers, useful in your example).
When you give parameters to a function, by default, those parameters are copies, not the original. So, function(int p, int q) creates two new variables : you can do whatever you want to q and p, the x and z would not change.
When you use pointers, you create a special variable, containing the adress of the variable. You can get the adress of any variable with the "&" sign. This is why, to call function(int* p, int* q) you need to write function(&y, &z).
To access the content of a pointer, you need to use the * sign in front of the pointer. Beware ! If you don't do this, you're not modifying the variable the pointer is pointing to, but the adress of the pointer (in your case, that would not be useful ; but in array manipulation, for instance, it can be very useful).
So, your function gets the adresses of two variables, and then do some computing.
This function does two things :
It computes something and give the result ;
During the computing, it gives to q the value of p, so z's value becomes y's value in the main.
Do some printf in your main, checking the value of your variables, before and after the function. Do it with a function using pointers and another one that does not use them, and it'll be much clearer to you.
And add a "int" in front of your function, since it returns something.
wnoise's answer is correct with but if you want to understand why you have such results below you can find reasoning.
this is not a pointer challenge but rather operator precedence.
Just treat *p and *q as You would use y & z
and with this code:
return(*p = (*p + *q) - (*q = *p));
remember that result of assigment is assigned value thus with *p = y = 15 and *q = z = 25
you have:
return(*p = (15 + 25) - (*q = *p));
return(*p = 40 - (*q = 15)); //*q -> z becomes 15
return(*p = 40 - 15);
return(*p = 25); // *p -> y becomes 25
return(25);

Why is the following C code illegal?

Consider a typical environment, why is the following code illegal in C?
{
int x;
&x = (int*) malloc(3*sizeof(int));
...
}
You can't assign something to the address of x because he address of x is not an lvalue
(An lvalue is "something that can be assigned to", i.e. it cannot be on the Left side of an equals sign)
Try
int* x;
x = (int*) malloc(3*sizeof(int)); // TODO: Call free(x)
Now x points to your allocated memory and you can do things like
int foo = *x;
int bar = x[0];
You can assign the address of x to something else, by using the & operator this way:
int x = 1;
int* y = &x; // y now holds the address of x
*y = 2; // Now x = 2
Becauase the address of x is not an lvalue - it is not something that can be modified. C allows you to change things that addresses point to - it does not allow you to change the addreses themselves.
Everyone is correct. The address of X at the time your code executes is a CONSTANT. In other words it says "Hey you can CHANGE where I, the compiler, store the 'x' variable."
you could do this
int main()
{
int* x;
*(&x) = malloc(3*sizeof(int));
}
The address of a variable cannot be changed. Instead you most likely want something like this:
int *x = (int *)malloc(3 * sizeof(int));
...
free(x);
&x returns pointer to x. You can't use it in the left part of an assignment, only on the right.
If you want to assign something to a pointer you have to declare it as a pointer, just like int *x;
Not that this is entirely valuable, but since no one else brought it up (all the above answers are correct, btw, and redundant, I agree that people should vote the right answer up, rather than saying the same thing over and over).
In your example, x is a stack variable. malloc gives you heap memory. That's probably not anything you need to think about too much in today's programming, but if you ever work in an environment where memory is at a premium, you'll want to save your stack as much as possible.
It's also worth noting that for some reason you're allocating 3*sizeof(int). Even if you COULD allocate memory to the stack, in your example, since you're only trying to get 1 int you'd only need 1* sizeof(int), the rest would be wasted.
That's the way the language is designed. To do what you want, use a pointer.

Resources