我有这个代码可以解决问题:
#include <stdio.h>
int main()
{
int a = 30000, b = 20,sum;
char *p;
p=(char *)a;
sum = (int)&p[b]; // adding a & b
printf("%d",sum);
return 0;
}
有人可以解释一下代码中发生了什么吗?
p = (char*)a;
sum = (int)&p[b]; // adding a & b
答案 0 :(得分:37)
&p[b]
基本上是糖:
&*(p + b)
*
和&
运算符在这里是反向运算并取消,只留下p + b
。演员阵容只是绕过C的类型检查。然而,使用指针的事件 的事实是显着的; C按比例缩放指针算术,根据定义,char *
缩放因子为1。
答案 1 :(得分:22)
我认为值得在其他答案中添加对c中指针,数组和内存位置的快速解释。
首先,c中的数组只是一块足以容纳数组中项目数的内存块(参见http://www.cplusplus.com/doc/tutorial/arrays/)
所以,如果我们说
int[5] example;
example[0] = 1;
example[1] = 2;
example[2] = 3;
example[3] = 4;
example[4] = 5;
假设int是32位,我们将有一块5 * 32bits = 160bits的内存块。 由于C是低级语言,它试图尽可能高效,因此尽可能存储关于数组的最少量信息,在这种情况下,可能的最小量是第一个元素的存储器地址。所以示例的类型可以表示为
int *example;
或者示例指向int。要获取数组中的项目,请将正确的数字添加到示例中存储的地址,并读取该内存地址处的数字。 如果我们假设记忆看起来像
Memory Address = Value (ints take up 4 bytes of space)
1000 = 1 <-- example
1004 = 2
1008 = 3
1012 = 4
1016 = 5
所以
int i = example[3]; //The 4th element
可以表示为
int i = *(example + 3 * sizeof(int));
int i = *(example + 3 * 4);
int i = *(1000 + 12);
int i = *(1012); // Fetch the value at memory location 1012
int i = 4;
sizeof(int)是4(int是32位,或4 * 8位字节)。如果你想做加法,你会想要一个8位或1 * 8位字节的字符。
回到你的代码
char* p; // declare p as a pointer to a char/
p = (char *)a; // point p at memory location 3000
// p[b] would be the 21st element of the "array" p =>
// p[20] =>
// p + 20 * sizeof(char) =>
// p + 20 * 1 =>
// p + 20 =>
// 3000 + 20 =>
// 3020
// the & operator in c gets the address of the variable so
sum = (int) &p[b];
// &p[b] => find the address pointed to by p[b] => 3020
// (int) casts this pointer to a int.
因此,sum被赋予数组的第21个元素的地址。
冗长的解释。
答案 2 :(得分:6)
p [b]返回数组p的第b个元素,相当于*(p + b)。 &amp; p [b]等于转换回int的p + b * sizeof(char)。
答案 3 :(得分:0)
如果问题是“在没有+运算符的情况下添加两个数字”,则这里有一个:
#include <stdio.h>
int main()
{
int a=5, b=7;
int a1=a, b1=b;
int res;
res = (++a1 * ++b1) - (a * b) -1;
printf("a1=%d b1=%d res=%d\n", a1, b1, res );
return 0;
}