本人大一菜鸟,想知道这样理解对不对

weixin_41515905 2017-12-24 01:21:40
int a[2][2]={{10,20},{30,40}};
int *p;
p=_____;
printf("%d",*p);
1.a+1
输出 30
a=&a[0],所以a+1即为&a[1],即为数组a[1]首地址
2.&a+1
输出 6356748
*p指向下一个数组的首元素,所以里面存的是乱码
3.a[0]+1
输出 20
*p指向a[0][1]
4.&a[0]+1
输出 30
将a[2][2]看成a[0]和a[1]两个一维数组,&a[0]+1即为&a[1]
5.&a[0][0]+1
输出 20
a[0]数组的首地址加一,所以为a[0][1]
6.a[0][0]+1
输出 error
a[0][0]无法取地址,所以错误
以上理解有哪些地方有错误吗,麻烦指点下。
...全文
739 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
weixin_41515905 2018-03-03
  • 打赏
  • 举报
回复
谢谢各位大佬的发言,我已经基本弄懂了,没有其他问题我就此结贴了。。谢谢大家。
bluestar2009 2018-03-01
  • 打赏
  • 举报
回复
引用 9 楼 zhao4zhong1 的回复:
理解讨论之前请先学会如何观察! 计算机组成原理→DOS命令→汇编语言→C语言(不包括C++)、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言(包括C++)、架构…… 对学习编程者的忠告: 多用小脑和手,少用大脑、眼睛和嘴,会更快地学会编程! 眼过千遍不如手过一遍! 书看千行不如手敲一行! 手敲千行不如单步一行! 单步源代码千行不如单步Debug版对应汇编一行! 单步Debug版对应汇编千行不如单步Release版对应汇编一行! 不会单步Release版对应汇编?在你想单步Release版C/C++代码片断的前面临时加一句DebugBreak();重建所有,然后在IDE中运行。(一般人我不告诉他!) VC调试时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化,这样过一遍不就啥都明白了吗。 对VC来说,所谓‘调试时’就是编译连接通过以后,按F10或F11键单步执行一步以后的时候,或者在某行按F9设了断点后按F5执行停在该断点处的时候。
好了···
bluestar2009 2018-03-01
  • 打赏
  • 举报
回复
引用 9 楼 zhao4zhong1 的回复:
理解讨论之前请先学会如何观察! 计算机组成原理→DOS命令→汇编语言→C语言(不包括C++)、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言(包括C++)、架构…… 对学习编程者的忠告: 多用小脑和手,少用大脑、眼睛和嘴,会更快地学会编程! 眼过千遍不如手过一遍! 书看千行不如手敲一行! 手敲千行不如单步一行! 单步源代码千行不如单步Debug版对应汇编一行! 单步Debug版对应汇编千行不如单步Release版对应汇编一行! 不会单步Release版对应汇编?在你想单步Release版C/C++代码片断的前面临时加一句DebugBreak();重建所有,然后在IDE中运行。(一般人我不告诉他!) VC调试时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化,这样过一遍不就啥都明白了吗。 对VC来说,所谓‘调试时’就是编译连接通过以后,按F10或F11键单步执行一步以后的时候,或者在某行按F9设了断点后按F5执行停在该断点处的时候。
VC6吗 alt 8 7 6 5 没有反应
赵4老师 2018-03-01
  • 打赏
  • 举报
回复
再供参考:
//char (*(*x[3])())[5];//x是什么类型的变量?
//
//分析C语言声明,关键是搞清楚这个变量是个什么东西(函数、指针、数组),
//是函数那么剩下的就是他的参数和返回值,
//是指针那剩下部分是说明他指向什么,
//是数组剩下的部分就是说明数组的成员是什么类型。
//解析C语言声明规则:
//从左侧第一个标识符开始,按照优先级进行结合。*表示是..的指针,const表示只读的,volatile表示可变的,[]表示是数组,()表示是函数。
//
//x和[3]结合说明是一个大小为3的数组,该数组的每个元素为一类指针,该类指针指向一类函数,该类函数无参数,返回一类指针,该类指针指向一个大小为5的char型数组
#include <stdio.h>
#include <typeinfo.h>
char num[5];
char (*x00())[5] {
    return #
}
int main() {
    char (*(*x[3])())[5];//是个数组,大小为3
    char (*(*x0  )())[5];//数组的元素,是个函数指针
    char (*( x00 )())[5];//函数原型,参数为空,返回值为指针
    char (*  x000   )[5];//返回值

    x0 = x00;
    x[0] = x0;
    x[1] = x0;
    x[2] = x0;
    printf("typeid(x).name() is %s\n",typeid(x).name());
    return 0;
}
//typeid(x).name() is char (* (__cdecl**)(void))[5]
  • 打赏
  • 举报
回复
p = (int *)a + 2; printf("%d\n", *p); 才能输出30 a+1不行,a+1=(int)&a + sizeof(int *)或者(long long)&a + sizeof(int *)取决于32位还是64位
赵4老师 2018-02-28
  • 打赏
  • 举报
回复
理解讨论之前请先学会如何观察! 计算机组成原理→DOS命令→汇编语言→C语言(不包括C++)、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言(包括C++)、架构…… 对学习编程者的忠告: 多用小脑和手,少用大脑、眼睛和嘴,会更快地学会编程! 眼过千遍不如手过一遍! 书看千行不如手敲一行! 手敲千行不如单步一行! 单步源代码千行不如单步Debug版对应汇编一行! 单步Debug版对应汇编千行不如单步Release版对应汇编一行! 不会单步Release版对应汇编?在你想单步Release版C/C++代码片断的前面临时加一句DebugBreak();重建所有,然后在IDE中运行。(一般人我不告诉他!) VC调试时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化,这样过一遍不就啥都明白了吗。 对VC来说,所谓‘调试时’就是编译连接通过以后,按F10或F11键单步执行一步以后的时候,或者在某行按F9设了断点后按F5执行停在该断点处的时候。
自信男孩 2018-02-28
  • 打赏
  • 举报
回复
引用 6 楼 weixin_41515905 的回复:
[quote=引用 3 楼 cfjtaishan 的回复:] 1.
a=&a[0],所以a+1即为&a[1],即为数组a[1]首地址
描述有点问题吧:a + 1即a[1]去掉&;即a + 1 等价a[1]; p = a+1即p = a[1]; 那照你这么说a+1==a[1]; 那么假设这是个a[3][2]数组,在p=a[1]的基础上再+1; 按理来说答案得到的是a[2]的地址,而由我一开始的测试可知 3.a[0]+1 输出 20 即在p=a[1]的基础上再+1输出的是a[1][1]; 这不就与答案有冲突了吗?
p是什么类型的?p是一重指针,p+1即a[1][1]而不是a[2]了,a[1]+1是a[1][1]。a[1]+1等价*(a+1) + 1注意a可以理解位int (*)[2],数组指针。
#include <stdio.h>

int main(void)
{
    int a[3][2] = {1, 2, 3, 4, 5, 6};

    int *p = a[1] + 1;
    int *q = *(a+1) + 1;

    printf("*p = %d\n", *p);
    printf("*q = %d\n", *q);

    return 0;
}
看一下p和q指向的内容是不是一样的。 变量+1时,需要注意变量的类型。
自信男孩 2018-02-28
  • 打赏
  • 举报
回复
p = a[1] = *(a+1) = &a[1] != a + 1 我的描述是这个关系
weixin_41515905 2018-02-28
  • 打赏
  • 举报
回复
[quote=引用 3 楼 cfjtaishan 的回复:] 1.
a=&a[0],所以a+1即为&a[1],即为数组a[1]首地址
描述有点问题吧:a + 1即a[1]去掉&;即a + 1 等价a[1]; p = a+1即p = a[1]; 那照你这么说a+1==a[1]; 那么假设这是个a[3][2]数组,在p=a[1]的基础上再+1; 按理来说答案得到的是a[2]的地址,而由我一开始的测试可知 3.a[0]+1 输出 20 即在p=a[1]的基础上再+1输出的是a[1][1]; 这不就与答案有冲突了吗?
赵4老师 2017-12-26
  • 打赏
  • 举报
回复
其实电脑开机后物理内存的每个字节中都有值且都是可读写的,从来不会因为所谓的new、delete或malloc、free而被创建、销毁。区别仅在于操作系统内存管理模块在你读写时是否能发现并是否采取相应动作而已。操作系统管理内存的粒度不是字节而是页,一页通常为4KB。
AlbertS 2017-12-25
  • 打赏
  • 举报
回复
第2项是偏移了一个数组吧,正好执行数组最后一个元素的后面,所以是乱码,有可能还宕机呢!
自信男孩 2017-12-25
  • 打赏
  • 举报
回复
1.
a=&a[0],所以a+1即为&a[1],即为数组a[1]首地址
描述有点问题吧:a + 1即a[1]去掉&;即a + 1 等价a[1]; p = a+1即p = a[1]; 2.
*p指向下一个数组的首元素,所以里面存的是乱码
若p = &a+1;那么p指向的是数组的a偏移sizeof(int) * 2 * 2后面的地址。该地址内的值是随机值,所以输出的是6356748 4. &a[0]+1等价(a+0) + 1;即a[1],p = a[1];而不是&a[1],若是&a[1]赋值给p那么类型也不匹配呢。 6. a[0][0]+1不是地址,相当于把20 + 1赋值给p那么,很可能会导致段错误;因为地址为21的地址空间可能是不可读的。 以上是个人理解,供参考;
weixin_41515905 2017-12-25
  • 打赏
  • 举报
回复
这个大佬讲得很清楚 http://blog.csdn.net/zdcsky123/article/details/6517811
韩小非 2017-12-25
  • 打赏
  • 举报
回复
编译器会给a[0]分配内存空间吗? a[0]是指二维数组第一行的首地址 他可以理解成一个指针 如果a=&a[0] 那a就是指向a[0]的指针了 就是指针的指针 这样理解第一个对吗?

33,311

社区成员

发帖
与我相关
我的任务
社区描述
C/C++ 新手乐园
社区管理员
  • 新手乐园社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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