鱼C论坛

 找回密码
 立即注册
查看: 1023|回复: 8

[已解决]C语言

[复制链接]
发表于 2020-3-8 21:07:57 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 老牛来学习 于 2020-3-8 21:19 编辑
#include<stdio.h>

int main()
{
    int *p ;
    printf("%p",p);
}

#include<stdio.h>

int main()
{
    int *p ;
    printf("%p",*p);
}

为什么第一个能输出一个值,第二个输出不了,他们两个不是一样的吗?

指针是指向目标标量的地址,那么野指针就是没有指定地址的指针,所以现在定义一个如:int *p 或 int *p=10;其中的指针p都没有给其定义地址,所以是野指针,这句话对吗?
或者说第二种int *p = 10;把10的值给赋给指针变量p,所以他不是野指针,但是由于只指向地址0x0a所以电脑执行会报错。

小甲鱼有一个题目说str[20] == *(str + 20) == *(20 + str) == 20[str]
为什么相等?数组名被解释为数组的第一个地址,上式中str才是数组名,写成20[str]直接把数组名都改了,电脑还怎么寻址呢?
最佳答案
2020-3-8 22:03:38
printf的%p是以指针形式打印指针变量。打印对象需要是一个指针,也就是一个地址。
第一个打印的是p的值,p是个指针。
第二个后面给的打印对象是*p, 即打印p指向的数据,而你定义指针p之后没有让p指向任何对象。打印p指向的数据会发生段错误,即你访问的数据是不可访问的。

int *p;这个定义很明显没有给指定p到底指向哪个地址,当然是野指针。
int *p=10; 看似给p赋值,这种强制让指针指向一个地址,但你并不知道地址为10的内存中到底是什么对象,给指针一个未知的对象的地址,当然也是野指针了。

str[20] == *(str + 20) == *(20 + str) == 20[str];
这个是C语言的语法决定的。前三个相等应该没有异议。第四个的寻址方式:str[20]的地址相当于str的初始地址+20;那么20[str]地址也就是20+str的首地址。那你说这两个值是不是一样的啊。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2020-3-8 21:11:58 From FishC Mobile | 显示全部楼层
没有初始化
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

发表于 2020-3-8 21:55:11 | 显示全部楼层
本帖最后由 4goodworld 于 2020-3-8 22:03 编辑
小甲鱼有一个题目说

弱弱地问一句,哪道题,我想去看看

关于第一个问题

printf("%p",*p);请问你打印的是什么%p是打印指针int*,你*p是int,东西不对等,就算打印出来,也不是你想要结果,打印不出来报错也是正常的,瞎来能搞出正确的结果吗?
另外,你不赋下值,直接拿来测试,你为啥总是能通过编译,我每次都会提醒 使用了未初始化的局部变量“p”
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-3-8 22:03:38 | 显示全部楼层    本楼为最佳答案   
printf的%p是以指针形式打印指针变量。打印对象需要是一个指针,也就是一个地址。
第一个打印的是p的值,p是个指针。
第二个后面给的打印对象是*p, 即打印p指向的数据,而你定义指针p之后没有让p指向任何对象。打印p指向的数据会发生段错误,即你访问的数据是不可访问的。

int *p;这个定义很明显没有给指定p到底指向哪个地址,当然是野指针。
int *p=10; 看似给p赋值,这种强制让指针指向一个地址,但你并不知道地址为10的内存中到底是什么对象,给指针一个未知的对象的地址,当然也是野指针了。

str[20] == *(str + 20) == *(20 + str) == 20[str];
这个是C语言的语法决定的。前三个相等应该没有异议。第四个的寻址方式:str[20]的地址相当于str的初始地址+20;那么20[str]地址也就是20+str的首地址。那你说这两个值是不是一样的啊。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

 楼主| 发表于 2020-3-8 22:12:04 | 显示全部楼层
4goodworld 发表于 2020-3-8 21:55
弱弱地问一句,哪道题,我想去看看

关于第一个问题


S1E22第二题,str[20] == *(str + 20) == *(20 + str) == [20]str,这是小甲鱼的原话,但是底下有人说甲鱼打错了,应该是20【str】
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-3-8 22:30:57 | 显示全部楼层
本帖最后由 4goodworld 于 2020-3-8 22:32 编辑
老牛来学习 发表于 2020-3-8 22:12
S1E22第二题,str[20] == *(str + 20) == *(20 + str) == [20]str,这是小甲鱼的原话,但是底下有人说 ...


应该是 20[str]
如果这么写是不会出问题的
我测试下
int main()
{
        int arr[2] = { 1,2 };
        int d = 1[arr];
        int c = arr[1];
        printf("%d %d",d,c );
}
然后断点看了反汇编代码:
012C3EA6  mov         eax,4  
012C3EAB  shl         eax,0  
        int d = 1[arr];
012C3EAE  mov         ecx,dword ptr [ebp+eax-0Ch]  
012C3EB2  mov         dword ptr [ebp-18h],ecx  
        int c = arr[1];
012C3EB5  mov         eax,4  
012C3EBA  shl         eax,0  
012C3EBD  mov         ecx,dword ptr [ebp+eax-0Ch]  
两者在底层代码上是一致的,哈哈
感谢分享,让我学到新的东西!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

 楼主| 发表于 2020-3-8 22:55:33 | 显示全部楼层
major_lyu 发表于 2020-3-8 22:03
printf的%p是以指针形式打印指针变量。打印对象需要是一个指针,也就是一个地址。
第一个打印的是p的值,p ...

您的意思是这样写是对的吗?但是我看了运算符格式的定义,上面写应该是数组名【整型表达式】。是为啥
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-3-8 22:57:47 | 显示全部楼层
4goodworld 发表于 2020-3-8 22:30
应该是 20[str]
如果这么写是不会出问题的
我测试下

但是C语言里面规定了下标运算符的用法,格式:
数组名【常量表达式】。。。
蒙圈,没学过汇编
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-3-8 23:00:18 | 显示全部楼层
老牛来学习 发表于 2020-3-8 22:55
您的意思是这样写是对的吗?但是我看了运算符格式的定义,上面写应该是数组名【整型表达式】。是为啥

这样写是对的啊,你自己写代码验证一下就知道了。数组名[下标]这种是最容易理解的,最好这样写。那些奇怪的表达知道就行,看别人代码能看懂就可以,因为总有一些人喜欢用非主流的写法,哈哈。自己写尽量不要用,因为过段时间自己有可能都看不懂了。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-1-15 20:32

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表