I've only been doing C for a few weeks so I am quite new to it.
I've seen things like
* (variable-name) = -* (variable-name)
in lecture notes but what exactly would it do? Would it just negate the value being pointed to?
Yes. When you add the star it means it is pointing to the value.
It is essentially saying: to the value at address (variable-name), become -1* the value of (variable-name).
If you are new to C, you may find it easier to use & instead of pointers. &'s are essentially the opposite of *. & doesn't point, it gives the address of a variable (which I find to be a simpler concept).
The following is an example which should demonstrate the use of * and &.
#include <stdio.h>
int main(void)
{
int blah = 6;
int *num = &blah;
(*num) = -(*num);
printf("%d\n", num); //Displays num
}
Yes it negates the value being pointed to. We cannot write operations on addresses so operations are done on deferenced pointers. Here, *d = -*c means:
*d = (-1) * (*c)
Sample code:
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int *c;
int *d;
d = (int *)malloc(sizeof(int));
c = (int *)malloc(sizeof(int));
*c = 9;
*d = -*c;
printf("%d", *d);
free(c);
free(d);
return 0;
}
Related
As I found on one site following code:
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int *p1 = malloc(4*sizeof(int)); // allocates enough for an array of 4 int
int *p2 = malloc(sizeof(int[4])); // same, naming the type directly
int *p3 = malloc(4*sizeof *p3); // same, without repeating the type name
if(p1) {
for(int n=0; n<4; ++n) // populate the array
p1[n] = n*n;
for(int n=0; n<4; ++n) // print it back out
printf("p1[%d] == %d\n", n, p1[n]);
}
free(p1);
free(p2);
free(p3);
}
Output:
p1[0] == 0
p1[1] == 1
p1[2] == 4
p1[3] == 9
Now following that code above I did this:
#include <stdio.h>
#include <stdlib.h>
#include "Header.h"
int main()
{
int *ip = (int*)malloc(1 * sizeof(int));
ip[0] = 2;
ip[1] = 9;
printf("%d %d",ip[0],ip[1]);
return 0;
}
Output: 2 9
So how then my pointer *ip can store more than one int when I only allocated bytes for single int?
You're writing into memory which is outside of the bounds of the array. Sadly, there is no compiler check for this, but it sometimes works.
Note: This is undefined behavior and should not be used under any circumstances.
Remember, ip[1] is equivalent to *(ip + 1), which is syntactically valid for any pointer, even if ip is pointing to single int and not an array of ints.
Dereferencing or writing to ip[1] is undefined behavior. Try adding free(ip) before the return 0 in your second program and observe the behavior then.
#include <stdio.h>
int main()
{
int* n;
*n = 20; // causes the crash
printf("%d\n", *n);
return 0;
}
but for some reason if i first set int* n = i then I can change the value with *n = 20
there a reason for this?
int i = 19;
int* n;
*n = i;
*n = 20;
edit: thank you everyone for helping i learned a lot from your answers.
int* n;
*n = i;
No, all you see (in both of your examples) is result of undefined behavior. Above you didn't initialize the pointer to point to a meaningful memory - by applying * operator you are dereferencing the pointer and telling it to write some value to the memory it points to, but since you didn't make it point to valid memory - you can't write through that pointer.
This would be fine
int x = 0;
int* n = &x; // Now your pointer points to valid memory
*n = 5; // Value of x will be 5 now
Yes, there is a reason. When you declare :
int* n;
pointer n shows nowhere. So when you try to set its value by
*n = 20;
the program crashes as you are trying to access the contents of a pointer showing nowhere.
On the other hand, when you declare
int i = 19;
int* n;
n = &i;
you make the pointer n show to some valid address. So when afterwards you assign
*n = 20;
you actually access the contents of a valid memory address.
The reason why you can't set the value using that pointer is because its not pointing to a memory address yet, you need to use malloc and give it something to point to.
Hope this helps :D
E.g
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
int *n;
n = malloc(sizeof(int));
*n = 20;
printf("n = %d\n", *n);
system("pause");
return 0;
}
Sorry if this post comes off as ignorant, but I'm still very new to C, so I don't have a great understanding of it. Right now I'm trying to figure out pointers.
I made this bit of code to test if I can change the value of b in the change function, and have that carry over back into the main function(without returning) by passing in the pointer.
However, I get an error that says.
Initialization makes pointer from integer without a cast
int *b = 6
From what I understand,
#include <stdio.h>
int change(int * b){
* b = 4;
return 0;
}
int main(){
int * b = 6;
change(b);
printf("%d", b);
return 0;
}
Ill I'm really worried about is fixing this error, but if my understanding of pointers is completely wrong, I wouldn't be opposed to criticism.
To make it work rewrite the code as follows -
#include <stdio.h>
int change(int * b){
* b = 4;
return 0;
}
int main(){
int b = 6; //variable type of b is 'int' not 'int *'
change(&b);//Instead of b the address of b is passed
printf("%d", b);
return 0;
}
The code above will work.
In C, when you wish to change the value of a variable in a function, you "pass the Variable into the function by Reference". You can read more about this here - Pass by Reference
Now the error means that you are trying to store an integer into a variable that is a pointer, without typecasting. You can make this error go away by changing that line as follows (But the program won't work because the logic will still be wrong )
int * b = (int *)6; //This is typecasting int into type (int *)
Maybe you wanted to do this:
#include <stdio.h>
int change( int *b )
{
*b = 4;
return 0;
}
int main( void )
{
int *b;
int myint = 6;
b = &myint;
change( &b );
printf( "%d", b );
return 0;
}
#include <stdio.h>
int change(int * b){
* b = 4;
return 0;
}
int main(){
int b = 6; // <- just int not a pointer to int
change(&b); // address of the int
printf("%d", b);
return 0;
}
Maybe too late, but as a complement to the rest of the answers, just my 2 cents:
void change(int *b, int c)
{
*b = c;
}
int main()
{
int a = 25;
change(&a, 20); --> with an added parameter
printf("%d", a);
return 0;
}
In pointer declarations, you should only assign the address of other variables e.g "&a"..
#include <stdio.h>
void swap (int *a, int *b)
{
int *tmp;
*tmp = *a;
*a = *b;
*b = *tmp;
}
int main ()
{
int x = 5;
int y = 7;
swap (&x,&y);
printf ("\n x = %d \n y = %d \n",x,y);
}
I'm using codeblocks, and this code won't work, and I don't understand why... On one computer it works perfectly but on the other it won't run at all.
Any help?
Thanks in advance.
int tmp;
tmp = *a;
*a = *b;
*b = tmp;
What you need is a variable tmp to store the value and not a pointer *tmp.
The below code really a poor way of doing this but
int *tmp = malloc(sizeof(int));
*tmp = *a;
*a = *b;
*b = *tmp;
Once done please free the memory using
free(tmp);
Gopi already corrected your code - adding on to the previous answer - i think this is good to know information for a newbie:
Section 4.1 states:
An lvalue (3.10) of a
non-function, non-array type T can be
converted to an rvalue. If T is an
incomplete type, a program that
necessitates this conversion is
ill-formed. If the object to which the
lvalue refers is not an object of type
T and is not an object of a type
derived from T, or if the object is
uninitialized, a program that
necessitates this conversion has
undefined behavior. If T is a
non-class type, the type of the rvalue
is the cv-unqualified version of T.
Otherwise, the type of the rvalue is
T.
When you try to dereference and uninitialized pointer the behavior is undefined. Undefined means anything can happen - there is no guarantee. So you can get different behavior in different environments.
From Wiki Making pointers safer
A pointer which does not have any address assigned to it is called a wild pointer. Any attempt to use such uninitialized pointers can cause unexpected behavior, either because the initial value is not a valid address, or because using it may damage other parts of the program. The result is often a segmentation fault, storage violation or wild branch (if used as a function pointer or branch address).
What you did here:
int *tmp;
*tmp = *a;
is that you created a pointer to int which is not pointing to anything - basically it contains some junk value (could be your pincode even - who knows).
Your mistake was to use uninitialized memory. Always allocate memory to a pointer before using it. Next, don't forget to free the allocated memory after you're done with it.
Also, you should add return 0; at the end of your main() function.
If you don't mind a second opinion, check the below code.
#include <stdio.h>
#include <stdlib.h>
void swap (int *a, int *b)
{
int *tmp = malloc(sizeof(*tmp));
*tmp = *a;
*a = *b;
*b = *tmp;
free(tmp);
}
int main ()
{
int x = 5;
int y = 7;
swap (&x,&y);
printf ("\n x = %d \n y = %d \n",x,y);
return 0;
}
If you want to use pointers, although it does not make any sense at all
void swap(int *a, int *b)
{
int tmp[1];
*tmp = *a;
*a = *b;
*b = *tmp;
}
here tmp is not strictly a pointer, but you can use the * indirection operator on it.
Or
void swap(int *a, int *b)
{
int value = *a;
int *tmp = &value;
*tmp = *a;
*a = *b;
*b = *tmp;
}
Or you can use malloc as Gopi already pointed out.
If you want to use pointers, then do use pointers:
#include <stdio.h>
void swap (int ** ppx, int ** ppy)
{
int * p = *ppx;
*ppx = *ppy;
*ppy = p;
}
int main (void)
{
int x = 5;
int y = 7;
int * px = &x;
int * py = &y;
printf ("\nx = %d\ny = %d\n", *px, *py);
swap (&px, &py);
printf ("\nx = %d\ny = %d\n", *px, *py);
return 0;
}
Result:
x = 5
y = 7
x = 7
y = 5
int main()
{
unsigned char a[3];
unsigned char (*p)[3]=NULL;
unsigned char *q=NULL;
int i = 0;
a[0]=0;
a[1]=1;
a[2]=2;
p=&a;
for(i=0;i<3;i++){
if((*p)[3] == a[3]){
printf("*p[%d]:%d a[%d]:%d",i,(*p)[3],i,a[3]);
}
}
}
o/p:
*p[0]:0 a[0]:0*p[1]:0 a[1]:0*p[2]:0 a[2]:0
Exited: ExitFailure 14
I want to copy an array of size 3 to a pointer and to do a comparision. I have written a sample program. But i'm getting an error value.
I ran this using an online c compiler . (codepad.org)
Please help me in identifying my mistakes.
Your variable p is an array, not a pointer. You can't re-assign an array to point somewhere else, so the line
p = &a;
is not valid.
Also, C indexes from 0 as you seem to know, so comparisons using index [3] for arrays of size 3 are not valid.
Further, in your comparison loop you're not actually using i to index, but instead always comparing using the invalid constant index [3].
It's not very clear from your code (q is not used, for instance), but it sounds as if you want to do something like:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
unsigned char a[3];
unsigned char *p;
p = malloc(sizeof a);
if(p != NULL) /* If allocation succeeded, p is valid. */
{
int i;
memcpy(p, a, sizeof a);
for(i = 0; i < sizeof a; ++i)
{
if(p[i] == a[i])
printf("p[%d]:%d a[%d]:%d\n", i, p[i], i, a[i]);
}
free(p);
}
Of course, this will always print all the numbers, since memcpy() will never fail to copy the memory. :)
Here You have declared the return type of main function as int, but you are not returning anything from it.
So return any integer value (like 1) or make the main function's return type void.