对于指针与数组的加减运算

#include<stdio.h>
int main(void) {
{
  int a[3][3] = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}; /*定义一个二维数组*/
  int *ptr = (int *)(&a + 1);  /*利用强制转换给指针赋值*/
  printf("%p\n",a);
  printf("%p\n",a+1);
  printf("%p\n",&a);
  printf("%p\n",&a+1);
  printf("%p\n",ptr);
  printf("%p\n",ptr-1);
  printf("%lu %lu\n",sizeof(a),sizeof(ptr));
	return 0;
}

运行结果如下:

名称地址差值(16进制下转为10进制)
a0xffffffdcc0ca+1与a
a+10x7fffffffdccccc-0c=36
&a0x7fffffffdcc0c&a+1与&a
&a+10x7fffffffdce4e4-0c=12
ptr0x7fffffffdce4prt-1与prt
ptr-10x7fffffffdce0e0-e4=4
  • 36 8(用sizeof算出的a与ptr的大小)

分析:

对于int a[3][3] (x,y属于0,1,2)

名称代表所占存储空间
&a以整个数组为一个存储单元(3*4)*3=36字节
a以一个a[x](为一个存储单元,a代表&a[0]3*4=12字节
a[x]以一个a[x][y]为一个存储单元,a[0]代表&a[0][0]4字节
  • 再来看看我们的指针ptr
  • int *ptr = (int *)(&a + 1)
  • 这里为什么要用(int *)强制转换呢?
  • 看看上面的解析就知道&a的大小为36字节!,ptr为一个一维指针(一般都为8字节),字节数都不相同,肯定要转换呀!!

  • 接下来就是ptr与ptr+k
  • 注意:指针的加减运算是增加k个存储单元,所以移动量就应该是 4(int型)*k,而不是指针所占的8字节

现在我们分析分析指针:
对于a[3][3]

名称代表指针+1
ptr一维指针若prt指向a,prt+1移动4字节
*(ptr)[3]二维指针若prt指向a,则prt移动4*3=12字节

综上所述:
对于那些一维指针,二维指针,一位数组,二维数组,乃至多维指针,多维数组本质上的差别便是在于所代表的的存储单元的字节数不同,所以在进行+1,-1等的加减运算时所每一次移动的字节数便不同(因为移动的字节数=所占的存储单元*移动次数(1,2,3……)

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
    建立如下类的层次结构:以Shape为抽象基类,从Shape类派生出Point、Line、Circle、Cylinder圆柱、Cone圆锥、Triangle、Rectangle和Polygon等类。分析这些类之间的关系,并编写合适的应用程序来测试该类的层次结构。   定义一个字符栈类CStack。私有数据成员:栈数组和指向栈顶的下标或指针;公有成员函数:构造函数、拷贝构造函数、压栈、出栈、清栈、访问栈顶元素、检测栈是否空,是否满等。用上述栈来做回文游戏。用户输入一行字符判断是否为回文。(回文:顺读和逆读字符串一样(不包括空格);如:“a man a plan a canal panama”,就是回文。) 编写一个让孩子进行分数运算训练的程序。每次训练随机产生10道题目,包含两个分数的、乘和除运算。每次训练前,用户可以设定回答问题的时间限制。如果用户没有设定时间限制,缺省的时间限制为每题30秒。程序运行时,给出一道题目后,等待用户的回答,用户回答后记录该题的回答结果和用时,直到用户10道题都回答完毕。用户回答完毕,对该次训练成绩进行判定,每道题按下面的规则给予记分    设计人民币类CRMB,数据成员为yuan、jiao和fen(如若为3元5角8分,则yuan为3、jiao为5、分8,jiao和fen逢十进一)。请为类设计实用的成员函数并重载+、-、++、+=、--、-=、>>、<<、==、>、<、*(乘以一个浮点数)、/(除以一个浮点数)及类型转换运算符(主要是double)。完成类的设计并进行测试。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值