Printing a variable in C that was not assigned a value - c

I put this code into eclipse and run it
main()
{
int *p, *q, *r;
int a = 10, b = 25;
int c[4] = {6,12,18,24};
p = c;
printf("p = %d\n" ,p);
}
the output I get is
p = 2358752
what is this number supposed to represent? Is it the address of the variable?
If what i'm saying above is true would my answer to the following question be correct?
so lets say the following are stored at the following locations
address variables
5000 p
5004 q
5008 r
500C a
5010 b
5014 c[0]
5018 c[1]
501C c[2]
5020 c[3]
so would would the line
p = c;
be 5014?

int *p,
The above statement defines p to be a pointer to an integer.
In the below statement, c is implicitly converted to a pointer to the first element of the array a.
p = c;
// equivalent to
p = &c[0];
Therefore, p contains the address of the first element of the array. Also, the conversion specifier to print an address is %p.
printf("p = %p\n", (void *)p);
// prints the same address
printf("c = %p\n", (void *)c);

Yes, p is the address of c, which is the same as the address of c[0]. And yes, in your second example, p would be equal to 5014.

Related

add local variable and pointer variable

I'm a beginner in C language.
I'm practicing several codes on my own, while doing I came across this algo.
Below is the code.
#include <stdio.h>
int main() {
int a = 1;
printf("value of a = %d\n", a);
printf("address of a = %u\n", &a);
int *p;
printf("value of p = %d\n", p);
p = 2;
printf("value of p = %d\n", p);
a = a+p;
printf("value of addition =%d\n", a);
return 0;
}
**OUTPUT**
value of a = 1
address of a = 947268620
value of p = 947268880
value of p = 2
value of addition =6
Why I'm getting 6 instead of 3,
is there anything I'm missing on result
because you're not setting the value of the address p is pointing to to 2, you're assigning/pointing the variable int *p to the value 2 in memory, which is not memory you should be accessing. Instead, you need to point p to memory you have access to (a variable or dynamically allocated memory) and dereference the pointer using *p = 2 which accesses the value that p is pointing to. Your code should instead look like this
int a = 1;
printf("value of a = %d\n", a);
printf("address of a = %u\n", &a);
int _p = 0;
int *p = &_p;
printf("value of p = %d\n", *p);
*p = 2;
printf("value of p = %d\n", *p);
a = a+*p;
printf("value of addition =%d\n", a);
One has to "walk right past" the compiler warnings about that code.
Below is the same code with coercive casting to silence some of the warnings. An additional calculation and print statement should make obvious how the compiler deals differently with the values of pointers (memory addresses) and the values of integers.
#include <stdio.h>
int main() {
int a = 1;
printf("value of a = %d\n", a);
printf("address of a = %u\n", &a); // incorrect format spec for printing address
int *p;
printf("value of p = %d\n", p); // uninitialised and undefined behaviour
p = (int*)2; // coercive casting integer to pointer-to-integer
printf("value of p = %d\n", p); // incorrect format spec for a memory address
a = (int)(a + p); // coercive casting address to integer
printf("value of addition =%d\n", a);
// ADDED these statements
a = 1; // restore value of a
a = a + (int)p; // coercive casting address to integer
printf("value of addition =%d\n", a);
return 0;
}
value of a = 1
address of a = 1703728
value of p = 1
value of p = 2
value of addition =6
value of addition =3 <== was this the expected result?
C will try to do its best with explicit program statements.
"Garbage in, garbage out."
Write correct code, not 'cute' code.
Thanks for your response Awayy. Helpful.
I got the output I needed. But the thing I need to know is, in what logic
the line a = a+p; gave 6 as result in my code.
As u said I'm assigning 2 as address to p(which is p = 0x2).
So, when the addition happens a = 1 and p = 0x2 which has a random value that we don't know that is because I'm not assigning a particular address to the pointer variable p. It results 6 I'm I right.

Why is it pointing to the same address?

#include<stdio.h>
int main() {
int x = 5;
int* p = &x;
*p = 6;
int** q = &p;
int *** r= &q;
printf("%d\n",*p); //dereferencing p
printf("%d\n",*q); //getting address of q
printf("%d\n",**q); //dereferencing q
printf("%d\n",**r); //getting address of r
printf("%d\n",***r); //dereferencing r
}
Variable q has the memory address of p while variable r has the memory address of q, then why does when trying to print the memory address of q and r same results are getting produced?
Your comments show that you have misunderstood a few things here.
printf("%d\n",*q); //getting address of q
You're NOT getting the address of q. You're dereferencing q, which happens to be the address of p. The * IS the dereferencing operator. If you want to print the address of q, then do this:
printf("%p\n", (void*)&q); // No asterisk and you should use the %p specifier for printing pointers.
So, because you have made the assignment p=&x; q=&p; then
**q is the same as x or *p
*q is the same as p
q is the the same as &p
&q is the address of q

Determine data type sizes using pointer in C

#include <stdio.h>
int main()
{
int a, b, c, d;
char *p = (char *)0;
int *q = (int *)0;
float *r = (float *)0;
double *s = 0;
a = (int) (p+1);
b = (int) (q+1);
c = (int) (r+1);
d = (int) (s+1);
printf("%d %d %d %d", a, b, c, d);
return 0;
}
As I've run it, it gives the output
1 4 4 8
From the output I assume it gives the sizes of data types(char, int, float and double) as output. But I don't understand how. Can someone please explain this program. What does (char *)0 means? What does (int)(p+1) do?
Thanks in advance.
What does (char *)0 means?
It casts 0 to a pointer. It is not necessary though. You could have used
char *p = 0;
or
char *p = NULL;
What does (int)(p+1) do?
p+1 evaluates to a pointer value. The (int) part casts the pointer to an int. It works on some platforms because the numerical difference between p and p+1 is sizeof(*p).
However, please note that this is undefined behavior. Don't use it in production code. Use the standard supported mechanism to get the size of a type -- sizeof(type).
int a = sizeof(char);
int b = sizeof(int);
int c = sizeof(float);
int d = sizeof(double);
printf("%d %d %d %d", a, b, c, d);
You could preserve the type that sizeof evaluates to by using size_t for the variables.
size_t a = sizeof(char);
size_t b = sizeof(int);
size_t c = sizeof(float);
size_t d = sizeof(double);
printf("%zu %zu %zu %zu", a, b, c, d);
In C, pointers and integers are interchangeable. So:
(char *)0 tells the compiler to look at the int 0 as if it were the address of a pointer to char. It then assigns that to p, a pointer to char.
C allows pointer arithmetic, so the expression p+1 computes the address where the compiler would put another char after p. The difference between the addresses of p and p+1 should be the size of 1 char in bytes.
To make sure C recognizes that as an int when it prints it out, the assignment a = (int) (p+1); casts p+1 (an address) to an int. Effectively, that's the size of a char.
Let's analyse each parts:
char *p = (char *)0;
A chart pointer is created and initialized to 0. The (char *) is here to cast the 0 to a char adress. So the pointer p points to the adress 0.
a = (int) (p+1);
(p+1) is the next adress after the current one (0) for a char* (p's current type). the (int) is there for the cast once again. For each type it will give the size because its value is the distance between the 1st adress and the second one.

Pointer to memory

I'm learning C and have some problems whit pointers.
I'm triying to print the memory slot for every declared variable, but when I declare the pointer for a Char[], it just does not work.
Here's my code:
int main () {
char a[3]; // this variable is my problem
int b;
float c;
char d;
int e=4;
char *pachar; //A char type variable for the pointer.
int *paint;
float *pafloat;
char *pacharr;
int *paintt;
pachar = &a; // when I try to assign the memory to the pointer, it shows a Warning message.
paint = &b;
pafloat = &c;
pacharr = &d;
paintt = &e;
printf("%p \n",pachar);
printf("%p \n",paint);
printf("%p \n",pafloat);
printf("%p \n",pacharr);
printf("%p \n",paintt);
return(0);
}
This is the warning message. Am I doing something wrong?
"warning: assignment from incompatible pointer type"
You declared a as an array of char:
char a[3];
Name a represents an array, which can be interpreted as a pointer to the initial element of the array. Therefore you do not need & when you assign a to a pointer:
pachar = a;
When you take an address of a in &a expression, you get a pointer to an array of three characters. Trying to assign a pointer-to-an-array to a pointer-to-char triggers compiler warning.
Instead of taking the address of a, you could take the address of the first element. The address of an array is the same as the address of its first element.
pachar = &a[0];
char a[3], *pachar;
pachar = a;
printf("Address = %u\n", a); // Base address of the Array. "&a" not required.
printf("Address = %u\n", &a[0]); // Address of the first element.
printf("Address = %u\n", pachar);// Address of the first element.
printf("Address = %u\n", pachar + 0); // Pointer Arithmetic ...
printf("Address = %u\n", pachar + 1); // a[1] is equivalent to pachar + 1
printf("Address = %u\n", &a[1]); // Similar to the above.

What's the difference between *d++ and (*d)++ in C?

as in the title, what's the difference because these two seem to get me the same results?
No they are not the same. Assume that d is a pointer to int:
int n = 0;
int* d = &n;
*d++; // d++ then *d, but d++ is applied after the statement.
(*d)++; // == n++, just add one to the place where d points to.
I think there is an example in K&R where we need to copy a c-string to another:
char* first = "hello world!";
char* second = malloc(strlen(first)+1);
....
while(*second++ = *first++)
{
// nothing goes here :)
}
The code is simple, put the character pointed by first into the character pointed by second, then increment both pointers after the expression. Of course when the last character is copied which is '\0', the expression results to false and it stops!
The increment ++ has higher operator precedence than the dereference *, so *d++ increments the pointer d to point to the next location within the array, but the result of ++ is the original pointer d, so *d returns the original element being pointed to. Conversely, (*d)++ just increments the value being pointed to.
Example:
// Case 1
int array[2] = {1, 2};
int *d = &array[0];
int x = *d++;
assert(x == 1 && d == &array[1]); // x gets the first element, d points to the second
// Case 2
int array[2] = {1, 2};
int *d = &array[0];
int x = (*d)++;
assert(x == 1 && d == &array[0] && array[0] == 2);
// array[0] gets incremented, d still points there, but x receives old value
In the official C terminology, these expressions do give you the same results, as they should. In the proper terminology, the "result" of a non-void expression is what that expression evaluates to. Both of your expressions evaluate to the initial value of *d, so not surprisingly, the results are the same.
However, an addition to a "result" every expression in C has zero or more so called "side effects". And side effects of these two expressions are completely different. The first expression increments the value of pointer 'd'. The second expression increments the value of '*d' (the pointed value).
The first increments the pointer, the second increments the value pointed to.
As an experiment, try this:
int main() {
int x = 20;
int *d = &x;
printf("d = %p\n", d);
int z = (*d)++;
printf("z = %d\n", z);
printf("d = %p\n", d);
int y = *d++;
printf("y = %d\n", y);
printf("d = %p\n", d);
}
They do return the same result, but the state change in your program is completely different.
This is easiest to understand if we just expand out the operations.
x = *d++;
// same as
x = *d;
d += 1; // remember that pointers increment by the size of the thing they point to
x = (*d)++;
// same as
x = *d;
*d += 1; // unless *d is also a pointer, this will likely really just add 1
I don't have a compiler handy.
a = (*d)++;
b = (*d);
is a==b? i don't think it is.

Resources