C#使用指针问题(很奇怪的现象)

手抓饼加辣 2009-11-04 10:25:21
先看代码:
unsafe
{
int num = 123456;
int* pN = #
int cou = 3;
Console.WriteLine("pn指向的地址:{0}", (uint)pN);
Console.WriteLine("pn的地址:{0}", (uint)&pN);
Console.WriteLine("pn指向地址存储的值:{0}", *pN);
Console.WriteLine("声明一个指向指针pN的指针pP");

//声明一个指向指针的指针
int** pP = &pN;
Console.WriteLine("pP是一个指向pN这个指针的指针,pP指向的地址为:{0}", (uint)pP);
Console.WriteLine("pP的地址为:{0}", (uint)&pP);


if (Console.ReadLine() == "1")
{
//下面这句要是注释了,cou就没有在堆栈中存储值
Console.WriteLine((int)&cou);
}
Console.ReadLine();
}
我是这样想的:假设num在堆栈中的地址从1242232开始,占4个字节,那么pN在堆栈中的地址应该是从1242228开始,占4个字节,然后cou从1242224开始,占4个字节,最后pP应该是从1242220开始,占4个字节。
可是我发现当我不要 Console.WriteLine((int)&cou);这一句,pP的地址就是从1242224开始了,也就是说cou不在堆栈中占据位置了。我非常不明白是为什么(就一句话,为什么影响这么大?),希望大家能帮帮我,在此谢谢大家了。
...全文
192 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
手抓饼加辣 2009-11-05
  • 打赏
  • 举报
回复
谁能帮我解释上述情况的原因?继续等待CSDN高人
soaringbird 2009-11-05
  • 打赏
  • 举报
回复
cou*=3就已经是用过了
手抓饼加辣 2009-11-05
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 maozefa 的回复:]
引用 10 楼 a6230589 的回复:
9楼的朋友我也有过你这样的猜测,于是在代码中加入了cou*=3等使用cou变量的代码,发现结果还是没有给cou分配内存空间。

呵呵,你那只是初始化变量,并非真正的使用变量,编译器这点“智商”还是有的
[/Quote]
恩,原来是这样,那怎么样才算使用变量呢?谢谢你啊maozefa。
  • 打赏
  • 举报
回复
楼上的xd,
能不能帮忙把Console.WriteLine((int)&cou); 这句去掉后的
IL代码贴上来
lzhdim 2009-11-04
  • 打赏
  • 举报
回复
呵呵,你不发结果啊。所以我就试了一下。跟你说的不一样。(VS 2008)

在声名cou的时候,已经分配内存给它了。下面是IL代码:

.method private hidebysig static void test() cil managed
{
.maxstack 2
.locals init (
[0] int32 num,
[1] int32* pN,
[2] int32 cou,
[3] int32** pP,
[4] bool CS$4$0000)
L_0000: nop
L_0001: ldc.i4 0x1e240
L_0006: stloc.0
L_0007: ldloca.s num
L_0009: conv.u
L_000a: stloc.1
L_000b: ldc.i4.3
L_000c: stloc.2
L_000d: ldstr "pn\u6307\u5411\u7684\u5730\u5740\uff1a{0}"
L_0012: ldloc.1
L_0013: conv.u4
L_0014: box uint32
L_0019: call void [mscorlib]System.Console::WriteLine(string, object)
L_001e: nop
L_001f: ldstr "pn\u7684\u5730\u5740\uff1a{0}"
L_0024: ldloca.s pN
L_0026: conv.u
L_0027: conv.u4
L_0028: box uint32
L_002d: call void [mscorlib]System.Console::WriteLine(string, object)
L_0032: nop
L_0033: ldstr "pn\u6307\u5411\u5730\u5740\u5b58\u50a8\u7684\u503c:{0}"
L_0038: ldloc.1
L_0039: ldind.i4
L_003a: box int32
L_003f: call void [mscorlib]System.Console::WriteLine(string, object)
L_0044: nop
L_0045: ldstr "\u58f0\u660e\u4e00\u4e2a\u6307\u5411\u6307\u9488pN\u7684\u6307\u9488pP"
L_004a: call void [mscorlib]System.Console::WriteLine(string)
L_004f: nop
L_0050: ldloca.s pN
L_0052: conv.u
L_0053: stloc.3
L_0054: ldstr "pP\u662f\u4e00\u4e2a\u6307\u5411pN\u8fd9\u4e2a\u6307\u9488\u7684\u6307\u9488,pP\u6307\u5411\u7684\u5730\u5740\u4e3a\uff1a{0}"
L_0059: ldloc.3
L_005a: conv.u4
L_005b: box uint32
L_0060: call void [mscorlib]System.Console::WriteLine(string, object)
L_0065: nop
L_0066: ldstr "pP\u7684\u5730\u5740\u4e3a\uff1a{0}"
L_006b: ldloca.s pP
L_006d: conv.u
L_006e: conv.u4
L_006f: box uint32
L_0074: call void [mscorlib]System.Console::WriteLine(string, object)
L_0079: nop
L_007a: call string [mscorlib]System.Console::ReadLine()
L_007f: ldstr "1"
L_0084: call bool [mscorlib]System.String::op_Equality(string, string)
L_0089: ldc.i4.0
L_008a: ceq
L_008c: stloc.s CS$4$0000
L_008e: ldloc.s CS$4$0000
L_0090: brtrue.s L_009e
L_0092: nop
L_0093: ldloca.s cou
L_0095: conv.u
L_0096: conv.i4
L_0097: call void [mscorlib]System.Console::WriteLine(int32)
L_009c: nop
L_009d: nop
L_009e: call string [mscorlib]System.Console::ReadLine()
L_00a3: pop
L_00a4: ret
}




lzhdim 2009-11-04
  • 打赏
  • 举报
回复
这个可以使用值类型和引用类型在CLR托管中的存储方式来解释。

其实你可以查看IL代码,即可找到原因了。。。
  • 打赏
  • 举报
回复
不要 Console.WriteLine((int)&cou);这一句

将导致cou没有被使用,编译的时候可能被优化没了。

只是一个猜想。
lzhdim 2009-11-04
  • 打赏
  • 举报
回复
你这个程序的运行结果,能发出来么。。。发出来再解释给你。。。
阿发伯 2009-11-04
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 a6230589 的回复:]
9楼的朋友我也有过你这样的猜测,于是在代码中加入了cou*=3等使用cou变量的代码,发现结果还是没有给cou分配内存空间。
[/Quote]
呵呵,你那只是初始化变量,并非真正的使用变量,编译器这点“智商”还是有的
手抓饼加辣 2009-11-04
  • 打赏
  • 举报
回复
9楼的朋友我也有过你这样的猜测,于是在代码中加入了cou*=3等使用cou变量的代码,发现结果还是没有给cou分配内存空间。
阿发伯 2009-11-04
  • 打赏
  • 举报
回复
这不是什么奇怪的事,大多数编译器都是这样:只有声明,而没有使用的局部变量会被忽略,有的编译器还有警告提示。
soaringbird 2009-11-04
  • 打赏
  • 举报
回复
你可能是选中了“优化代码”。
zjh222 2009-11-04
  • 打赏
  • 举报
回复
C#的指针是变态的,你用好了才怪
手抓饼加辣 2009-11-04
  • 打赏
  • 举报
回复
2楼的朋友,我不是猜想,是运行后发现的结果。

111,125

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Creator Browser
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧