所以,我跟随"让我们C"本书,他们有一个指针示例,你能解释为什么i
和j
的值在这种情况下会改变值吗?:
main( )
{
int i = 3, *j, **k ;
j = &i ;
k = &j ;
printf ( "\nAddress of i = %u", *k ) ;
printf ( "\nAddress of j = %u", &j ) ;
}
输出
地址i = 65524
地址j = 65522
我在C
中理解,例如int i =3; int k=5
的新变量声明被C分配了不同的内存位置,但似乎无法理解为什么输出不同的值?
答案 0 :(得分:4)
您期望*k
(与i
的地址相同)和&j
(j
的地址)相同。它们是int *
v / s int **
不同的类型和不同的值。
切勿使用%u
打印地址,而是使用:
printf ( "\nAddress of i = %p", (void *)*k ) ;
另一方面,如果您比较&j
和k
,那么这些应该相同。
例如:
printf ( "%p v/s %p\n", (void *)&j, (void *)k);
答案 1 :(得分:2)
因为您在第一个printf
语句中打印指向k 的指针,而不是k
的实际值。 k
保存j
引用的值,因此如果您希望两个语句相同,则只需打印k
。
答案 2 :(得分:1)
第1点:使用%p
打印地址。另外,将相应的参数强制转换为(void *)
第2点: *k
(类型int *
)和&j
(类型int **
) 两种不同的东西。也许你想要打印
k
和&j
(int **
} *k
和j
(int *
} 答案 3 :(得分:1)
printf ( "\nAddress of i = %u", *k );
这里* k打印存储在j的值而不是j的地址。
要获取j的地址,您需要打印k而不取消引用它。
现在* k表示取消存储在存储位置200处存储的k(即)值的值。
存储在200的值是100,它是i的地址,而不是j的地址。
答案 4 :(得分:0)
当您的程序启动时,操作系统内核会根据许多条件决定将程序放在何处以及如何将其映射到内存中。
因此,当您连续多次启动时,内存位置可能会也可能不会改变。
这就是为什么你不能在你的程序中硬编码绝对内存位置的原因,你总是选择一个起点如何知道(例如,数组的第一个元素)并从这里导航到你的内存中。< / p>
答案 5 :(得分:0)
当你的程序启动时,每个变量都会在内存中占有一席之地:
Padding
在你的情况下,我们知道这些地址已经决定:
int i = 3, *j, **k ;
运算符address of (int i) = 65524
address of (int* j) = 65522
address of (int** k) = unknown
获取变量的地址,以便获得您观察到的输出。
答案 6 :(得分:0)
给出代码
int i = 3, *j, **k ;
j = &i ;
k = &j ;
然后以下是真的:
**k == *j == i == 3
*k == j == &i
k == &j
即,表达式**k
,*j
和i
都具有int
类型并且评估为3
,表达式*k
,j
和&i
都有int *
类型并评估为i
的地址,而k
和&j
的表达式为{ {1}}并评估int **
的地址。
所以,
j
使用printf( "value of i = %d\n", i );
printf( "value of i (through j) = %d\n", *j );
printf( "value of i (through k) = %d\n", **k );
printf( "address of i = %p\n", (void *) &i );
printf( "address of i (through j) = %p\n", (void *) j );
printf( "address of i (through k) = %p\n", (void *) *k );
printf( "address of j = %p\n", (void *) &j );
printf( "address of j (through k) = %p\n", k );
printf( "address of k = %p\n", (void *) &k );
转换说明符打印指针值。它期望%p
作为其对应的参数,这是C中为数不多的几个地方(可能是唯一的地方),您需要将指针值显式地转换为void *
。