作者 : 卿笃军

你有没有想过,对一个一维数组名取地址,然后用这个地址进行加减运算。这会出现什么样的结果呢?

演示样例:

int a[5] = {1,2,3,4,5};

int *p = (int *)(&a+1);

printf("%d\n",*(p-1));

这个输出会是多少呢?

咦?为什么第二行须要强制转化类型呢?

答:a是一个一维数组的名字,&a相当于一个指向一维数组的指针。怎么感觉这么熟悉?指向数组的指针,那不就是行指针吗?int (*p)[]。

行指针+1,就是对指针进行加减操作,其结果还是一个行指针~~~原来如此,须要强制转换为单指针。

能够看一段代码,例如以下:

#include <stdio.h>

int main()
{
int a[5] = {1,2,3,4,5};
int *p = (&a+1); return 0;
}

编译会出现例如以下警告(警告行数:int *p = (&a+1);):

上面的警告也告诉我们,&a是一个行指针~~~

那么,输出结果是多少呢?

答:当然是5。

为什么?

答:上面不是说了嘛,&a就是一个行指针,那就是指向一行的指针咯。行指针+1,不就指向下一行了,这里一行为[5]个,那么int *p = (int *)(&a+1)就要在a的基础上偏离5个位置:(例如以下:上一行表示偏离位数,下一行表示a[]中相应的数据)

0  1  2  3  4  5

1  2  3  4  5  *

咦,这不是越界了吗?移动五位都跑出a[]数组处于' * '号位置了。哦,我看到printf()输出了。你输出的是*(p-1),这里p是一个单指针-1就是往左位移一位即可了,那不就是又回到5的位置了吗?原来是这样,输出结果是5 。

以下我们用一段代码来显示位移情况~~~

#include <stdio.h>

int main()
{
int a[5] = {1,2,3,4,5};
int *p = (int *)(&a+1); //+1相当于移动了5位 printf("%p\n%p\nbit = %d\n",a,p,p-a);
printf("%d\n", *(p-1)); return 0;
}

C语言 对数组名取地址的更多相关文章

  1. 搬运1:关于对C语言中数组名取地址加减等操作的一点探究

    对于数组名取地址强制转换的操作 偶然在晚上学了C语言指针后网页闲逛找题时,被一个数组名取地址搞糊涂了,在自己试验加探索后我稍微悟了一点东西. 代码如下: #include<stdio.h> ...

  2. C语言的数组名和对数组名取地址

    http://blog.csdn.net/zdcsky123/article/details/6517811 相信不少的C语言初学者都知道,数组名相当于指针,指向数组的首地址,而函数名相当于函数指针, ...

  3. C语言中对数组名取地址

    在C/C++中,数组名相当于一个指针,指向数组的首地址.这里“相当于”不代表等于,数组名和指针还是有很多区别的,这个在<C陷阱与缺陷>里有详尽的讲述.而这里要说的是对于数组名取地址的这么一 ...

  4. 对数组名取地址 a[ ],&a

    C语言规定,数组名代表数组的首地址,也就是第0号元素的地址.所以a==&a[0] 但对数组名取地址时却要注意了,在理解“对数组名取地址”这一表达式的含义时一定要记住:数组名是“数组”这种变量的 ...

  5. 数组名取地址所算数运算应注意的&quot;trap&quot;

    数组名取地址所算数运算应注意的"trap" 直接看代码: #include <stdio.h> int main() { int array[5]; printf(&q ...

  6. 数组名和数组名取地址&

        在C中, 在几乎所有使用数组的表达式中,数组名的值是个指针常量,也就是数组第一个元素的地址. 它的类型取决于数组元素的类型: 如果它们是int类型,那么数组名的类型就是“指向int的常量指针“ ...

  7. C语言指令数组名和数组名取地址

    以下C语言指令:int a[5] = {1, 3, 5, 7, 9}; int *p = (int *)(&a + 1); printf("%d, %d", *(a + 1 ...

  8. C语言数组名取地址。。。

    int main(){ int a[5] = { 1, 2, 3, 4, 5 }; printf("%08X ,%08X ,%08X ,%08X", a, &a, a + ...

  9. 对数组名取地址&a和 数组首地址a

    #include <iostream> using namespace std; ] = {,,,,}; int main() { cout<<a<<" ...

随机推荐

  1. asp.net微信开发第九篇----模板消息的使用

    微信平台的模板消息,使用起来非常好,效果如下: 和平时我们微信中关注信用卡官方微信,如果消费了,信用卡官方微信就返回一个模板消息给我们告知,余额还有多少,消费了多少. 使用的步骤,我只简单介绍了怎么使 ...

  2. Mysql 视图笔记

    1.       视图的定义 视图就是从一个或多个表中,导出来的表,是一个虚拟存在的表.视图就像一个窗口(数据展示的窗口),通过这个窗口,可以看到系统专门提供的数据(也可以查看到数据表的全部数据),使 ...

  3. mahout学习-1

    一. 安装软件 需要安装如下文件: java, Eclipse, Maven,Hadoop,mahout 二. 推荐系统简介 每天,我们都会对一些事物表达自己的看法,喜欢,或不喜欢,或不在乎.这些都在 ...

  4. redis数据结构HyperLogLog

    如果我们要实现记录网站每天访问的独立IP数量这样的一个功能 集合实现: 使用集合来储存每个访客的 IP ,通过集合性质(集合中的每个元素都各不相同)来得到多个独立 IP ,然后通过调用 SCARD 命 ...

  5. em px 简单换算

    大部分的网页设计者在CSS代码编写中总是先对整体定义字体尺寸,中文情况下一般为12px,而其实这样以来在通过IE顶部菜单中的“察看-文字大小”设置已无任何 作用.对字体感觉太小的浏览者而言无疑是种很不 ...

  6. PHP生成数字+字符混合型字符串

    以下是一个用PHP随机生成字符+数字混合型的随机字符串,可用来生成会员ID.用户密码/密钥等内容,函数简单,代码如下: <?php function generate_rand($l){ $c= ...

  7. Python中的正斜杠与反斜杠

    首先,"/"左倾斜是正斜杠,"\"右倾斜是反斜杠,可以记为:除号是正斜杠一般来说对于目录分隔符,Unix和Web用正斜杠/,Windows用反斜杠,但是现在Wi ...

  8. The initialize list of C++ Class

    性能问题之外,有些时场合初始化列表是不可或缺的,以下几种情况时必须使用初始化列表 常量成员,因为常量只能初始化不能赋值,所以必须放在初始化列表里面 Error1(constchar* constmsg ...

  9. PreparedStatement 和 Statment区别

    PreparedStatement vs Statment 1)语法不同:PreparedStatement可以使用预编译的sql,而Statment只能使用静态的sql 2)效率不同: Prepar ...

  10. 再次探讨C++的动态绑定和静态绑定

    以前在学习C++的时候,对动态绑定和静态绑定的理解是:静态绑定是编译时决定的,非虚函数基本都是静态绑定:而动态绑定用于虚函数,是为了实现多态.这样理解没什么大的问题,但我一直疑惑的是,既然静态绑定可以 ...