被C中的指针弄糊涂了
我刚讲到课本上的要点,但解释得不够好,所以我需要一些帮助 我知道指针是什么,它们做什么。例如,我非常理解以下示例:被C中的指针弄糊涂了,c,pointers,C,Pointers,我刚讲到课本上的要点,但解释得不够好,所以我需要一些帮助 我知道指针是什么,它们做什么。例如,我非常理解以下示例: #include <stdio.h> int main () { int num = 5; int *point; point = # *point = 8; printf("%d %d", num, *point); return 0; } #包括 int main() { int num=5
#include <stdio.h>
int main ()
{
int num = 5;
int *point;
point = #
*point = 8;
printf("%d %d", num, *point);
return 0;
}
#包括
int main()
{
int num=5;
整数*点;
点=&num;
*点=8;
printf(“%d%d”,num,*点);
返回0;
}
点指向num(将num的地址存储为其值)。然后我解引用point来改变num的原始值
现在考虑同一示例的修改版本:
#include <stdio.h>
int main ()
{
int num = 5;
int *point;
point = 8;
printf("point: %d\n", point);
printf("sum (%d) = num (%d)+ point (%d)", num+point, num, point);
return 0;
}
#包括
int main()
{
int num=5;
整数*点;
点=8;
printf(“点:%d\n”,点);
printf(“总和(%d)=num(%d)+点(%d)”,num+点,num,点);
返回0;
}
我有几个问题:
1-为什么甚至可以将正常值(8)指定给指针(点)?指针不应该只存储指向其他东西的地址吗?8号线发生了什么
2-我编译了代码,第二次打印显示:
总和(28)=数量(5)+点数(8)
为什么总和等于28?5+8等于13。发生了什么?在第二个示例中,您为指针指定了8。我希望你从你的编译器那里得到一个很好的警告。但是你可以指定8。只是不要去引用它。您可能会遇到分段错误或更糟的情况。num+point的总和非常合理。这叫做指针算术。点是指向整数的指针。计算机上的int是4字节。num+point的总和是(5*sizeof(int))+8,在您的系统上是28。您可以将
点
指向内存地址8(或0x00000008)。它相当于point=(int*)8代码>我得到了友好的<代码> <代码>错误,因为我使用C++,我想它可以保护我免于愚蠢。
为什么5+8=28?如果向T类型的指针添加一个数字n,则将该指针移动n个T类型的元素。您的计算机正在处理32位整数,大小为4字节,因此8+(5*4)=28。因为几乎所有C编译器都将指针作为整数来实现,以支持指针算法
int arr[10];
int *ip = arr;
arr[2] = 42; // this is equivalent to:
*(ip + 2) = 42; // or
*(2 + ip) = 42;
比如说,&arr[0]
(整数数组arr
的第一个元素的地址)是0xcafe0000
。假设一个int
值占用内存中的4个字节。然后&arr[1]
位于0xCAFE004
,&arr[2]
位于0xCAFE008
,以此类推,以4字节为增量
编译器会看到:
int i = arr[5]; // which is equivalent to:
int j = *(arr + 5);
并获取地址0xcafee0000
,然后添加(5*sizeof(int))
,在取消引用之前,该地址将显示为0xcafee0028
这就是为什么当您将任何ol'整数转换为指针类型时,请说:
int *p = (int*) 8;
然后加上:
p = p + 5; // p := 28
编译器将获取p
的值,并将其添加到操作数5
乘以int
的大小。对于计算机而言,指针只是具有特殊含义的整数值,即内存地址值。因此,将整数值分配给指针始终是可能的,尽管最终可能会得到一个空指针
num+指针为28的原因是您的计算机是因为您使用的计算机中的地址是32位。所以C有一个叫做指针算术的特性,这意味着对指针加上/减去任何值实际上会增加4*num,因为机器上的每个32位字中有4个字节。结果得到point+num==8+(4*5)
==编辑
另外,当您在C中执行指针算术时,计算机实际上会向指针添加数据类型的字节数。例如,如果您声明:
int num = 5;
char * point;
那么当你这么做的时候
point = 8;
point+num==8+5==13的结果,因为在大多数C实现中,char是一个单字节。指针是一个数字,就像int
是一个数字一样。为指针指定硬编码值是合法的,但会发出警告
point = 8;
但是没有意义,除非你使用的是嵌入式系统,并且知道地址是什么
虽然您的程序经受住了内存访问限制,但您不知道内存地址8的值是多少。所以你不会理解计算的结果。这是未定义的行为,因为程序没有在该地址设置值。1-为什么甚至可以将正常值(8)分配给指针(点)?指针不应该只存储指向其他东西的地址吗?第8行发生了什么? 指针存储内存地址是正确的,但该内存地址仅记录为一个数字。通常,指针的值要大得多,但没有什么可以阻止您将内存地址分配给指针(8)。但不要期望使用此地址。一种常用的方法是使用 与
int *point = 0;
2-我编译了代码,第二次打印显示:sum(28)=num(5)+point(8)为什么sum等于28?5+8等于13。发生了什么事?
指针算法的工作方式与您最初预期的不同,除了存储内存位置外,指针还具有内存类型:
int *point;
在这种情况下,点
知道它指向一个int
。因此,当指针递增时,它的位置不会增加一个字节,而是增加sizeof(int)
,在您的例子中是4个字节。这意味着point++
或point=point+1
将指针移动到它认为当前指向的对象的大小,原因是它可以很容易地沿着相同类型对象的数组或内存块移动
要了解这个概念,请尝试处理这段代码
#include <stdio.h>
int main()
{
int x;
int * ptr = &x;
for(int i = 0; i < 5; i++)
{
printf("pointer address: %p\n", ptr + i);
}
return 0;
}
#包括
int main()
{
int x;
int*ptr=&x;
对于(int i=0;i<5;i++)
{
P
#include <stdio.h>
int main()
{
int x;
int * ptr = &x;
for(int i = 0; i < 5; i++)
{
printf("pointer address: %p\n", ptr + i);
}
return 0;
}