Differences between int variable and pointer variable in C [closed] - c

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
#include <stdio.h>
int j;
int *ptr;
int main(void)
{
j = 13232323;//adress I want to assign
ptr = j;//assign the adress to the pointer
printf("%d",ptr);
}
OUTPUT:13232323
Am I doing wrong as assigning adress directly to a pointer? Pointer is nothing but a variable contains value in the address form, so I constructed an address and then assign it to the pointer,it works as it was supposed to be, except that I can not construct an address containing characters ABCDEF,so,what's the big difference between int and pointer?
EDIT:
This code means nothing but solely for testing purpose

Actually what your trying is out of your eagerness., I agree, I too often do this way.
The Very first thing is if you store 13232323 in a pointer variable, the hex value of it is OXC9E8C3., so really at the time of your assigning the pointer variable (ptr) doesnot know whether really it is a valid address or invalid address. But when you dereference this address with *ptr, then comes the problem. It tries to seek the value in the address.
Then there are 2 cases..
Really if what you assigned is a valid address , then it will return the value. (Practically impossible case)
Mostly your address will be a invalid one, hence program will crash (Segmentation fault).
So, even though your program compiles, runs, until and unless you store a valid address in ptr., ptr has no use.
Your Q: It works as it was surposed to be,except that I can not construct an
address containing characters ABCDEF,so,what's the big difference
between int and pointer? printf("%d",ptr);
I think you are asking, whatever the case, I cannot store ABCDEF, hence ptr works same as int type, so what is the difference between integer and pointer?
Here it is :
You cannot deference an integer value, where as pointer can do it.
Hence it is called as pointer :)
You are seeing only numbers because you are printing the address with %d, trying printing with %x or %p.
Atlast, do you notice the compiler warning, warning: assignment makes pointer from integer without a cast , because ptr = j; in that ptr is of int* type, and j is of int type.

you need to use %x, or you can send *ptr to the printf
printf("%d", *ptr);// if you are using this you need to know what are you pointing at, and that it will be an integer
or
printf("%x", ptr);
as the comments below says, it is always better to use %p instead of %x because %x invoke undefined behaver. also when using %p one should cast his pointer to (void *)

Your code is invalid. C language does not allow this assignment
ptr = j;
Integer values cannot be converted to pointer types without an explicit cast (constant zero being the only exception).
If the code was accepted by your compiler, it simply means that your compiler extends the language beyond its formal bounds. Many compilers do that in one way or another. However, if your compiler accepted this code without issuing a diagnostic message (a warning or an error), then your compiler is seriously broken.
In other words, the behavior of our program has very little (or nothing) to do with C language.

In C you can do most of the type conversion, even the types are totally unrelated. It may cause warning though. make sure that your type conversion make sense.

Syntactically, you are not doing anything wrong here. You can anyways, assign one pointer to another, and since they only contain addresses like the one you assigned here, this is what actually happens during the pointer assignment.
But you should never assign a random address and try to dereference it, because your program doesn't have access to a memory location unless alloted by the machine. You should request the memory from the machine using a function like malloc().
As for differences between pointers and integers, the biggest one is that you can't use a dereference operator (*) on an integer to access the value at the address it contains.
And you can construct addresses using ABCDEF by prefixing your address value with 0X or 0x to signify a hexadecimal notation.

Am I doing wrong as assigning adress directly to a pointer?
Yes, the only integer types that are supposed to work directly with pointers as you do are intptr_t and uintptr_t, if they exist. If they don't exist you are not supposed to do this at all. Even then you would have to use an explicit cast to do the conversion.
Pointer is nothing but a variable contains value in the address
form,so I constructed an adress and then assign it to the pointer,it
works as it was surposed to be,except that I can not construct an
address containing characters ABCDEF,so,what's the big difference
between int and pointer?
No, on some architectures pointers can be more complex beasts than that. Memory can e.g be segmented, so there would be one part of the pointer value that encodes the segment and another that encodes the offset in that segment. Such architectures are rare nowadays, nevertheless this is something that is still permitted by the C standard.

you need ptr to hold the address of j by doing the following
ptr = &j;
ptr hold, equal to, the address of j
and you want to print the content of whats ptr is pointing to by the following
printf("%d",*ptr);
and to get the address of ptr do the following
printf("%x",ptr);
x for the hex representation

Related

Dereferenced vs non Dereferenced pointers ( and the explanation behind them ) [duplicate]

This question already has answers here:
Why Use Pointers in C?
(4 answers)
Closed 5 years ago.
Why is it we have to dereference a pointer ( that has already been linked to another variable ) every time we want to work on the variable its linked to? If there's a pointer that's linked to a variable ( an int for example ) isn't dereferencing it on-top of everything else a bit redundant? Do standard ( non-dereferenced ) pointers serve their own separate purposes? What can we do with a pointer that hasn't been dereferenced?
example : pPrice vs *pPrice
I'm learning my first programming language C and I've been wondering this for some time.
When working with people who haven't worked with pointers before, I like to point out that a pointer isn't special compared to other primitive types; it's simply an integer, just like ints or chars. What's special about it is how we interpret its value - specifically, we interpret its value as the location (address) of another value. This is a little bit similar to how even though chars are really just integers, we interpret them to be characters based the ASCII encoding. Simply because we interpret a pointer's value to be an address, we can perform operations such as reading or writing the memory at the address it's specifying.
Like you said, we can still access the pointed to memory as usual, but now we have some additional benefits.
For example, we can change the pointer's value, thereby pointing it to a different place in memory. This might be useful if we want to write a generic function that modifies a given object, but you want to dynamically decide which object to pass to it.
Also, the pointer itself is a constant, defined size (usually 32 or 64 bits), yet it could point to an object of any arbitrary size (e.g. a vector, string, or a user defined type). This makes it possible for us to pass around or store a handle to the object without passing/storing the entire object, which might be expensive.
I'm sure there are a million more use cases that I'm leaving out, but these are a couple to get you started.
tl;dr: An integer variable is distinct from a reference to an integer variable.
In C, the idea of a "variable" is very specific. In reality, it is the area in memory which holds the value of a variable. The symbol is a convenient symbol name by which the C code can refer to the value, to the content of the memory area. A "reference" is the address of the memory location. Since C is strongly typed, each symbol indicates how to interpret the memory to which it is associated. (Whew!)
So,
int i;
i refers to a memory location which holds an integer.
i=5;
fills that memory location with the binary representation for 5.
int *p;
means p is associated with a memory location which contains a pointer (aka address) to an integer location. So we can write,
p = &i;
where &i is the explicit address of the memory location of the integer value. So, p and i refer to quite different kinds of things. Since p is the address of an integer, we can dereference it (i.e., follow the address) to get to the actual integer value at the address location (the one assocated with i).
*p = 6;
i = 6;
Both assignment statements are functionally equivalent (they both set the same memory location to integer 6) since both i and the dereferenced p, *p, refer to the same memory location. Noteably, i is inextricably tied to the memory location, while *p can point elsewhere (though, p is inextricably to the integer-pointer memory location that refers to integers).
pPrice may be modified to point to a different price.
int a = 1,
b = 2,
*p = &a;
printf("%d\n", *p);
p = &b;
printf("%d\n", *p);

C pointer initialization differences

I am new to C and have some questions about the pointer.
Question 1 What`s differences b/w the following two? Which way is better to initialize a pointer and why?
int *p=NULL;
int *p;
#include <stdio.h>
void main()
{
char *s = "hello";
printf("%p\t%p",s);
//printf("%p\t%p",&s) it will give me unpredictable result every time
//printf("%p\t%p",(void *)&s) it will be fine
//Question3: why?
}
Question 2: I try to google what is %p doing. According to my reading, it is supposed to print the pointer. It that mean it print the address of the pointer?
Question 1, these are definitions of pointer p. One initializes the pointer to NULL, another leaves it uninitialized (if it is local variable in a function, and not global variable, global variables get initialized to 0 by default). Initializing with NULL can be good, or it can be bad, because compiler can warn you about use of uninitialized variables and help you find bugs. On the other hand compiler can't detect every possible use of uninitialized variable, so initializing to NULL is pretty much guaranteed to produce segmentation fault if used, which you can then catch and debug with a debugger very easily. Personally I'd go with always initializing when variable defined, with the correct value if possible (if initialization is too complex for single statement, add a helper function to get the value).
Question 2, %p prints the address value passed to printf. So printf("%p", pointer); gets passed value of variable pointer and it prints that, while printf("%p", &pointer); (note the extra & there) gets passed address of the variable pointer, and it prints that. Exact numeric format of %p is implementation defined, it might be printed just as a plain number.
Question 3 is about undefined behavior, because format string has more items than what you actually pass to printf. Short answer is, behavior is undefined, there is no "why". Longer answer is, run the application with machine code debugger and trace the execution in disassembly view to see what actually happens, to see why. Note that results may be different on different runs, and behavior may be different under debugger and running normally, because memory may have different byte values in different runs for various reasons.
1) The first is an initialization (to NULL in this case) the second is only a declaration of p as a pointer to int, no initial value is assigned to p in this case. You should always prefer an initialization to prevent undefined behavior.
2) You should cast to void* when using %p to print out a pointer (beware that you are using it too many times in your format specifier). The memory address to which p points is printed.
1)
int *p = NULL
defines and initializes a pointer 'p' to NULL. This is the correct way to initialize pointers in order to get "Seg Fault" if you forget to assign a valid address to this pointer later.
int *p
Only defines a pointer "p" with an unknown address. If you forget to assign a valid value to this pointer before using it, then some compilers will notify you about this mistakes while some others will not and you may access a non-valid address and get a run time error or undefined behaviour of the program.
2) "%p" is printing the address where the pointer is points. Since the pointer holds an address, then "%p" prints this address.
printf("%p\t%p",s);
So the first "%p" will print the address where the pointer "s" points which is the address which stores the string "hello". However, note that you are using twice "%p" but you providing only one pointer to print its address !!
Most compilers will not scream about this cause it is effect-less; however try to avoid it.
Answer1 :
int *p=NULL;
p is a pointer to a int variable initialized with NULL. Here NULL means pointer p is not pointing to any valid memory location.
int *p;
p is a pointer to a int variable. p in uninitialized. Reading uninitialized variables is Undefined Behavior. (one possibility if try to use is that it will throw a segmentation fault)
Answer2:
It prints content of pointer. I mean base address of string "hello"
The main difference is that in *p = NULL, NULL is a pre-defined and standard 'place' where the pointer points.
Reading from Wikipedia,
The macro NULL is defined as an implementation-defined null pointer constant,
which in C99 can be portably expressed as the integer value 0
converted implicitly or explicitly to the type void*.
This means that the 'memory cell' called p contains the MACRO value of NULL.
If you just write int *p, you are naming the memory cell with the name p but this cell is empty.

What address is this pointer assignment returning?

I was playing around with pointers the other day and came up with the following code where I explicitly cast an int variable to int * and print out the address of the explicitly casted variable
#include <stdio.h>
int main (void)
{
int d;
int *p1, *p2;
printf("%p\n", p1 = &d);
printf("%p\n", p2 = (int *) d);
return 0;
}
Here's the output:
ffbff71c
ffbff878
My question is what is that second address and what is contained there?
Garbage - you're printing out the value of an uninitialized variable. It's just total coincidence that it looks like your other address; initialize d to get a meaningful answer.
In the second print, you are not printing an address, but a value converted to an address!
In the first assignment, you're taking the address of the variable, which is just some RAM address. In the second assignment, you're converting the variable's value to a pointer. Since the variable is not initialized, that's the garbage value located at that RAM address.
It is just a random address in memory since d is not initialized.
As others have pointed out, you are converting an indeterminate value to a pointer. Performing that conversion, or indeed doing anything with that value other than overwriting it, produces undefined behavior.
If d's value were set prior to the conversion, then it would matter that C explicitly permits integers to be converted to pointers. However, for this case and most others, the standard says:
the result is implementation-defined, might not be correctly aligned, might not point to an entity of the referenced type, and might be a trap representation.
[C2011, 6.3.2.3/5]
So basically, don't do that unless you know enough to determine reliably for yourself what the result will be with your particular combination of code, C implementation, compile and link options, and platform.

C - What does int *p; p=15; does?

What is the difference between these two code samples? When I print the variable p, it prints the assigned value like below.
int *p;
p = 51;
printf("%d",p);
Output: 51
When I try to assign p=15, am I making memory address "15" in the ram as a pointee to the pointer p? When I try to add int c = 5 +p; it gives output as 71. Why am I getting 71?
I thought that the memory address "15" could store any information of the OS, programs, etc. But it exactly stores int for precise. Though I change the value p = 150; it gives int . How is that possible? What's happening under the hood?! I really don't understand.
Your code is illegal. Formally, it is not C. C language prohibits assigning integral values to pointer types without an explicit cast (with the exception of constant 0)
You can do
p = (int *) 51;
(with implementation-defined effects), but you cannot do
p = 51;
If your compiler allows the latter variant, it is a compiler-specific extension that has nothing to do with standard C language.
Typically, such assignment makes p to point to address 51 in memory.
On top of that, it is illegal to print pointer values with %d format specifier in printf. Either use %p or cast pointer value to proper integer type before using integer-specific format specifiers.
So you're telling that pointer that it points to 0x15. Then, you tell printf to print it as a decimal integer, so it treats it as such.
This reason this works is that on a 32 bit system, a pointer is 4 bytes, which matches the size of an int.
p points to a place in memory. *p is the contents of that space. But you never use the contents, only the pointer.
That pointer can be viewed as just a number, so printf("%d",p) works. When you assign a number to it, it interprets that as an offset into memory (in bytes). However, the pointer is supposed to contain ints, and when you add a number to a pointer, the pointer advances by that many spaces. So p+5 means "point to the int 5 spaces past the one you're pointing at now", which for 4-byte ints means 20 bytes later, hence the 71.
Otherwise, you've said you have a pointer to an int, but you're actually just doing all your stuff to the pointer, not the int it's pointing to.
If you actually put anything into the place you were pointing, you'd run into all kinds of trouble. You need to allocate some unused memory for it (e.g. with malloc), and then read and write values to that memory using *p.

Another C pointer Question

The following code :
int *a;
*a = 5;
will most likely result in a segmentation fault and I know why.
The following code :
int a;
*a = 5;
won't even compile.
(gcc says : invalid type argument of unary *).
Now, a pointer is simply an integer, which is used
for storing an address.
So, why should it be a problem if I say :
*a = 5;
Ideally, this should also result in a segmentation fault.
A pointer is not an integer. C has data types to
a) prevent certain programming errors, and
b) improve portability of programs
On some systems, pointers may not be integers, because they really consist of two integers (segment and offset). On other systems, the "int" type cannot be used to represent pointers because an int is 32 bits and a pointer is 64 bits. For these reasons, C disallows using ints directly as pointers. If you want to use an integral type that is large enough to hold a pointer, use intptr_t.
When you say
int a;
*a = 5;
you are trying to make the compiler dereference something that is not a pointer. Sure, you could cast it to a pointer and then dereference it, like so,
*((int*)a) = 5;
.. and that tells the compiler that you really, really want to do that. BUT -- It's kind of a risky thing to do. Why? Well, in your example, for instance, you never actually initialized the value of a, so when you use it as a pointer, you are going to have whatever value is already at the location being used for a. Since it looks like it is a local variable, that will be an un-init'd location in the function's stack frame, and could be anything. In essence, you would be trying to write the value 5 to some undetermined location; not really a wise thing to do!
It's said to illustrate that pointers merely store addresses, and that addresses may be thought as numbers, much like integers. But usually addresses have a structure (like, page number, offset within page, etc).
You should not take that by word. An integer literally stores a number, which you can add, subtract etc. But which you cannot use as a pointer. An integer is an integer, and a pointer is a pointer. They serve different purposes.
Sometimes, a cast from a pointer to an integer may be necessary (for whatever purposes - maybe in a OS kernel to do some address arithmetic). Then you may cast the pointer to such an integer type, previously figuring out whether your compiler guarantees correct sizes and preserves values. But if you want to dereference, you have to cast back to a pointer type.
You never actually assign "a" in the first case.
int* a = ?
*a = 5; //BAD. What is 'a' exactly?
int a = ? //but some int anyway
*a = 5; //'a' is not a pointer!
If you wish to use the integer as a pointer, you'll have to cast it first. Pointers may be integers, but conceptually they serve different purposes.
The operator * is a unary operator which is not defined for the integer data type. That's why the statement
*a = 5;
won't compile.
Also, an integer and a pointer are not the same thing. They are typically the same size in memory (4 bytes for 32 bit systems).
int* a — is a pointer to int. It points nowhere, you haven't initialized it. Please, read any book about C before asking such questions.

Resources