int main ()
{
int num_1 = 111;
int *p = &num_1;
int &ref1 = *p;
int *(&ref2) = p;
printf("&ref2 : %d\n", &ref2);
printf("*ref2 : %d\n", *ref2);
printf("ref2 : %d\n", ref2);
return 0;
}
I get pointer literally points address.
So in int &ref1 = *p; ref1's address is equal to num_1's address, hence have the same value as num1 which is 111.
However, what I don't understand is ref2 part.
If int *(&ref2) is the value of ref2 variable, shouldn't it have the same address of the num_1?
If int *(&ref2) is the value of ref2 variable, shouldn't it have the same address of the num_1?
The declaration int *(&ref2) = p; defines ref2 to be a reference to p.
Part of your misunderstanding may come from wrong output you get from using inappropriate printf conversion specifiers; it's wrong to print addresses with %d - in your first and third printf use %p instead. It might become clearer if you add
printf("p : %p\n", p);
*a=10
*b=20
How to swap them without using the third variable? Output should be like
*a=20
*b=10
Not sure if the interviewer was looking for XOR over something else but it seems you can simply use +, -, and x. Should work if a is bigger or negative as well.
*a+=*b
*b-=*a
*b=*b x -1
*a-=*b
In your example that would give us:
*a+=*b --> *a = 30
*b-=*a --> *b = -10
*b=*b x -1 --> *b = 10
*a-=*b --> *a = 20
Here is a simple code to do so:
#include <stdio.h>
#include <stdlib.h>
void usingXOR(int** x, int** y){
unsigned long long a = (unsigned long long)*x;
unsigned long long b = (unsigned long long)*y;
a = a^b;
b = a^b;
a = a^b;
*x = (int*)a;
*y = (int*)b;
}
void main(){
int x=5;
int y=10;
int* a = &x;
int* b = &y;
//If you only want to swap the values the pointers are pointing to
//Here the addresses the pointers are holding dont get swapped
(*a) = (*a)+(*b);
(*b) = (*a)-(*b);
(*a) = (*a)-(*b);
//If you want to swap addresses in the pointers
//printf("Before swap address a: %p\n", a);
//printf("Before swap address b: %p\n", b);
//usingXOR(&a,&b);
printf("a: %d\n", *a);
printf("b: %d\n", *b);
//printf("After swap address a: %p\n", a);
//printf("After swap address b: %p\n", b);
}
char a = 'x';
char *b = &a;
char *c = &b;
printf("%p\n", c); //outputs 0060FF04
printf("%p\n", &b); //outputs 0060FF04
printf("%p\n", *c); //outputs 0000000B
printf("%p\n", *&b); //outputs 0060FF0B
printf("%p\n", &a); //outputs 0060FF0B
So basically, the concept of pointers is new to me and was running some tests to understand it better. Anyway as you can see, the 1st and the 2nd output is similar as I expected. however, dereferencing char c outputs 0000000B instead the memory address of a which is 0060FF0B.
So my question is if c = &b then how come *c != *&b?
The type of c should be char **, not char *. The program interprets 0x0060FF0B as a 1-byte char, giving 0x0B.
I have int A, B, C. And A is in range 0-9999, B is 0-99, C is 0-99.
Because the function must return only one double, I think of putting them all into one number. Otherwise I need to call function three times.
But I cannot write an efficient code to do this. This will be called millions times, so it should be quite effective, but no ASM.
I need a function double pack3int_to_double(int A, int B, int C) {}
Couldn't you just store A + 1000B + 100000C?
For example, if you wanted to store A = 1234, B = 6, and C = 89, you'd just store
89061234
CCBAAAA
You can then extract the numbers by casting the double to an int and using standard integer division and modulus tricks to recover the individual values.
Hope this helps!
If A<10,000 and B & C <100, A can be expressed with 14 bits, and B & C with 8 bits. Thus you need 30 bits in total.
You could therefore pack/unpack the integers by shifting it to the right place:
int packed = A + B<<14 + C<<22;
A = packed & 0x3FFF; B = (packed >> 14) & 0xFF; C = (packed >> 22) & 0xFF;
Bit shifting is of course MUCH faster than multiply/divide, and you can cast the int to a double and vice versa.
This is technically not legal C code, so you would use this at your own risk:
typedef union {
double x;
struct {
unsigned a : 14;
unsigned b : 7;
unsigned c : 7;
} y;
} result_t;
The C standard doesn't allow using a union member to write a value and a different one to read it out, but I am not aware of a compiler that does the static analysis to diagnose such a problem (it doesn't mean one won't do so in the future). Also, using certain int values may result in a trap representation for a double. But, if you know your system will not generate any trap representations, you can consider using this.
double pack3int_to_double(int A, int B, int C) {
result_t r;
r.y.a = A;
r.y.b = B;
r.y.c = C;
return r.x;
}
void unpack3int_from_double (double X, int *A, int *B, int *C) {
result_t r = { X };
*A = r.y.a;
*B = r.y.b;
*C = r.y.c;
}
You can use out parameters in function call and retrieve all 3 int variables.
You could return a NaN double with the data stored in the mantissa. That gives you 53 bits to utilize. Should be plenty.
http://en.m.wikipedia.org/wiki/NaN
Inspired by your answers, this is what I come up so far. This should be quite efficient, and only 32 bits are used, so the exponent of the double is not touched.
struct pack_abc {
unsigned short a;
unsigned char b, c;
int safety;
};
double pack3int_to_double(int A, int B, int C) {
struct pack_abc R = {A, B, C, 0}; // or 0 could be replaced with something smater, like NaN?
return *(double*)&R;
}
void main() {
int w = 1234, a = 56, d = 78;
int W, A, D, i;
double p = pack3int_to_double(w, a, d);
// we got the data packed into 'p', now let's unpack it
struct pack_abc *R = (struct pack_abc*) & p;
printf("%i %i %i\n", (int)R->a, (int)R->b, (int)R->c);
}
I want to convert a pointer *int to its real value int, in Go language.
How do you do it?
Just use the * operator. For example:
var i int = 10 // `i` is an integer, with value 10
var p *int = &i // `p` is a pointer to an integer, its value is a memory address
var n int = *p // `n` is again an integer, with value 10
Once you get the hang of what's happening, the above code can be written in a more idiomatic (and simpler) way like this, assuming that we're inside a function:
i := 10
p := &i
n := *p