对数组地址的理解,如

int c[2] = {2,3};
int(*cp)[2] = &c;
cout << &c[0] << c << cp << endl;

输出都是一样的。。结论:当对数组用&比如&c,那么意思就是“对数组取地址或者取得数组的地址”,而数组的地址返回的就是第一个元素的地址,加上数组名本身也是一个指针,故c与&c会有一样的结果。

本版讨论很多对于C语言中指针和数组的认识和看法,
下面是我自己对指针的一些粗浅认识,写的有点乱, 希望对新手有所帮助
请大家批评指正。也欢迎大家积极讨论。

1. 指针变量也只是普通的变量

很多C语言的初学者都将指针变量看的很神秘,实际上,就像其他的普通变量(比如int类型的),指针变量也是一种普通变量,他具有其他变量的一切特征。

例如:
int main()
{
int q=10;
int *pi=0;
pi = &q;
printf ("%d\n", *pi);
}

main中声明并定义了一个自动变量p,他的类型是pointer-to-int.一旦定义了p,编译器就要给p分配内存空间。main结束后,p被自动释放。pi和q在这些方面没有丝毫不同。

结论:指针变量没有那么神秘,指针变量只是一个普通变量

2. 指针变量与其他变量的关系

那么,指针的特殊性表现在什么地方呢?

指针特殊就特殊在对他所存储的值的解释上和对他的使用上。

在上例中,pi的值会被解释成内存中的一个地址,以这个地址开始的一块内存则表示一个int型的数.

但是,即使在执行了pi = &q之后,pi和q也没有什么直接的关系:改变pi的值不会影响q,改变q的值也不会影响pi,他俩是两个独立的变量,有各自的存储空间。

C语言赋予了指针特殊的本领就是:可以存储别的变量的内存地址,也可以利用指针变量本身的值去间接的操作别的变量.这两种能力是通过两个操作符来完成的 : &和*。

pi = &q;                        //利用q的内存地址对pi进行赋值
printf ("%d\n", *pi);     //利用pi的值去间接的读q的值

sizeof(pi)跟sizeof(q)根本就是两码事. pi不会自动根据自己去寻找q的,只有你显示的使用*pi才可以.

结论:假设指针pi存储的是q的地址。pi和q没有任何直接的关系。只有*pi才和q有直接的关系。

3. C语言中的函数参数传递方式

很多人的另外一种误解是,C语言中有两种函数传递方式:按值传递和按地址传递。

造成这种误解的原因就是对上面所说的两点理解的不够。

void swap1( int a, int b)
{
int temp;
temp = a;
a = b;
b = temp;
}

void swap2( int* pa, int* pb)
{
int temp;
temp = *pa;
*pa = *pb;
*pb = temp;
}

int main()
{
int i=10, j=5;
int *pi, *pj;
pi = &i;
pj = &j;
swap1(i, j);
printf("i=%d, j=%d\n", i, j);
swap2(pi, pj);
printf("i=%d, j=%d\n", i, j);
}

很多人会认为swap1是按值传递,而swap2是按指针传递。其实,C语言只有一种函数参数传递方式:按值传递。

swap1大家都明白,我说一下swap2。

实际上,我在第一点中已经指出,指针只是一个普通变量而已。在对swap2的调用swap2(pi, pj)中, pi和pj的值分别被copy到swap2中的pa和pb中。现在,i,pi和pa是3个完全不同的变量,但pi和pa的值相同,他们存的都是i的地址。在swap2中,利用*pa就可以读写i了,同样利用*pb就可以读写j了,所以swap2就可以完成i和j的交换了。但是,pi和pj的值通过swap2是无法改变的。

也就是说, swap2使用的参数传递方式仍然是按值传递,只不过传递的是指针的值,然后利用指针有可以间接访问其他变量而已.

结论:C语言只有一种函数参数传递方式:按值传递.

4. 指针与数组

4.1 数组名的类型

在C语言中,指针与数组千丝万缕的联系.看下面的例子:

int a[5];
int b[3][5];
int *pa1[5];
int (*pa2)[5];

那么a,b,pa1,pa2的类型到底是什么呢?

很多人将a的类型误解成为一级指针,即const pointer to int,

而将b的类型误解成为二级指针,即const pointer to the pointer to int;

a不是const pointer to int类型的,我们是可以从下面这个事实推出来的:
sizeof(a)跟sizeof(int*)是不同的.

只能说,a是array of 5 ints类型的

而b则是array of 3 arrays of 5 ints类型的

这里之所以把pa1和pa2列出来,主要是给大家区别一下:
pa1是array of 5 int pointers类型的,
而pa2是pointer to array of 5 ints类型的

4.2 数组名的运算

大家经常会遇到关于数组名的运算问题,比如

int a[5]={1, 2, 3, 4, 5};
int b[3][5]={{1,2,3,4,5}, {6,7,8,9,10}, {11,12,13,14,15}};
printf("%d", *(a+2));
printf("%d, %d\n", **(b+2), *(*b+2));

在进行上面的运算时,有下面的似非而是的结论:

&a可以看作是pointer to array of 5 ints类型的
所以&a+1,这里的“1”是指5*sizeof(int)

a是array of 5 ints类型的,但是a的值是什么呢?a的值其实是一个
pointer to int

*a的值则是一个int,即a[0];

&b可以看作是pointer to array of 3 arrays of 5 ints类型的
所以&b+1,这里的“1”是指3*5*sizeof(int)

b是array of 3 arrays of 5 ints类型的,但是b的值却是一个
pointer to array of 5 ints

*b是array of 5 ints类型的,但是*b的值却是pointer to int类型的

**b的值则是int类型的,即b[0][0];

推而广之,则对于 int c[n1][n2]...[nm]的m维数组(m后面的数字为下标),有下面的结论(或者说计算方法):
先将c扩展为int c[n1][n2]...[nm][1]; (最后一个是数字1,不是字母l)

1.&c的单位“1”为n1*n2*...*nm*1*sizeof(int)
sizeof(&c)等于存储一个指针的大小,其值与sizeof(int*)相同;

2.令c1代表*...*c,共有i(0<i<=m-1)个*,则他的单位“1”为n(i+2)*...*nm*1*sizeof(int),其中(i+2)等是下标
sizeof(c1)=n(i+1)*...*nm*sizeof(int)

3.令c2代表*...*c,共有m个*,表示数组中第一个整数
sizeof(c2)=sizeof(int)

例如:int c[3][4][5][6];
先转换成int c[3][4][5][6][1];
&c+1相当于地址加3*4*5*6*1*sizeof(int), sizeof(&c)的值等于sizeof(int*);
c+1相当于地址加4*5*6*1*sizeof(int), sizeof(c)=3*4*5*6*1*sizeof(int);
**c+1相当于地址加6*sizeof(int), sizeof(**c)=5*6*1*sizeof(int);
****c就是数组中第一个整数

4.3 一种常见错误

int b[3][5];
int **p=b;

有些人误认为p+1的值和b+1是相同的,其实不然

类似于

T1 b1;
T2* b2=(T2*)(&b1); //T1,T2为两种不同的类型

这样的话,b2+1是按sizeof(T2)进行增加的
而&b1+1是按照sizeof(T1)进行增加的
指针进行类型转换后,其运算跟他自身的类型有关,而与他指向的东东无关

C++指针与数组的更多相关文章

  1. C与指针(结构体指针,函数指针,数组指针,指针数组)定义与使用

    类型 普通指针 指针数组(非指针类型) 数组指针 结构体指针 函数指针 二重指针 定义方式 int *p; int *p[5]; int (*p)[5]; int a[3][5]; struct{.. ...

  2. 11-C语言指针&一维数组&字符串

    一.用指针遍历数组元素 1.最普通的遍历方式是用数组下标来遍历元素 1 // 定义一个int类型的数组 2 int a[4] = {1, 2, 3, 4}; 3 4 int i; 5 for (i = ...

  3. 指针与数组的区别 —— 《C语言深度剖析》读书心得

    原书很多已经写的很清楚很精炼了,我也无谓做无意义的搬运,仅把一些基础和一些我自己以前容易搞混的地方写一下. 1. 意义: 指针: 指针也是一种类型,长度为4字节,其存放的内容只能是一个地址(4字节). ...

  4. 不可或缺 Windows Native (18) - C++: this 指针, 对象数组, 对象和指针, const 对象, const 指针和指向 const 对象的指针, const 对象的引用

    [源码下载] 不可或缺 Windows Native (18) - C++: this 指针, 对象数组, 对象和指针, const 对象,  const 指针和指向 const 对象的指针, con ...

  5. 指针 与 数组 以及 a 与 &a的区别

      指针 与数组 并没有什么关系,   指针就是指针,指针变量在32位系统下,永远占4个byte,其值为某一个内存的地址,指针可以指向任何地方,但是不是任何地方你都能通过这个指针变量访问到;   数组 ...

  6. c/c++ 函数指针 指针函数 数组的引用 指针数组 数组指针

    1.指针数组数组指针 引用数组 数组的引用 int *a[10] 指针数组 每一个元素都是一个指针 Int (*a)[10] 数组指针 P指向一个含有10个元素的数组 Int (&a)[10] ...

  7. 深入理解C语言中的指针与数组之指针篇

    转载于http://blog.csdn.net/hinyunsin/article/details/6662851     前言 其实很早就想要写一篇关于指针和数组的文章,毕竟可以认为这是C语言的根本 ...

  8. 转: 浅谈C/C++中的指针和数组(二)

    转自:http://www.cnblogs.com/dolphin0520/archive/2011/11/09/2242419.html 浅谈C/C++中的指针和数组(二) 前面已经讨论了指针和数组 ...

  9. 转:浅谈C/C++中的指针和数组(一)

    再次读的时候实践了一下代码,结果和原文不一致 error C2372: 'p' : redefinition; different types of indirection 不同类型的间接寻址 /// ...

  10. C语言指针与数组的定义与声明易错分析

    部分摘自<C语言深度解剖> 1.定义为数组,声明为指针 在文件1中定义: char a[100]; 在文件2中声明: extern char *a; //这样是错误的 这里的extern告 ...

随机推荐

  1. 【Coursera-ML-Notes】线性回归(下)

    模型表示 多变量的线性回归也叫做"多元线性回归".首先还是先明确几个符号的含义. \(x{^{(i)}_j}\):第i个训练样本的第j个特征,比如面积,楼层,客厅数 \(x^{(i ...

  2. numpy切片和布尔型索引

    numpy 标签(空格分隔): numpy 数据挖掘 切片 数组切片是原始数组的视图.这意味着数据不会被复制,视图上的任何修改都会直接反映到源数组上 In [16]: arr Out[16]: arr ...

  3. 基于Kubernetes(k8s)的RabbitMQ 集群

    目前,有很多种基于Kubernetes搭建RabbitMQ集群的解决方案.今天笔者今天将要讨论我们在Fuel CCP项目当中所采用的方式.这种方式加以转变也适用于搭建RabbitMQ集群的一般方法.所 ...

  4. 1.安装CDH5.12.x

    安装方式安装前准备安装步骤安装过程修改/etc/hosts设置ssh 互信修改linux 系统设置安装JDK1.8安装python2.7安装mysql/postgreysql数据库安装ntp设置本地y ...

  5. Linux 应用笔记

    Linux 应用笔记 Linux 应用笔记 小书匠 Raspberry Pi 常用命令 CentOs Raspberry Ubuntu python 实用教程 Vim 权限问题 内存分配 shell ...

  6. 20162328蔡文琛week09

    学号 2016-2017-2 <程序设计与数据结构>第X周学习总结 教材学习内容总结 数据库是为了其他程序提供数据的应用软件. 关系书就哭通过唯一的标识符在不同表的记录见建立了关系. JD ...

  7. activiti工作流已办和待办查询sql

    最近项目中遇到一个问题,需要activiti的工作流表和业务表关联分页查询,然而我对于工作流的查询并不太熟悉,所以学习并总结如下. 想看看activiti到底怎么查询的待认领和待办.已办的查询sql, ...

  8. 第三章——供机器读取的数据(CSV与JSON)

    本书使用的文件.代码:https://github.com/huangtao36/data_wrangling 机器可读(machine readable)文件格式: 1.逗号分隔值(Comma-Se ...

  9. IOS开发NSBundle使用

    bundle是一个目录,其中包含了程序会使用到的资源. 这些资源包含了如图像,声音,编译好的代码,nib文件(用户也会把bundle称为plug-in). 对应bundle,cocoa提供了类NSBu ...

  10. JS DOM视频相关的知识

    1.实现点击a标签改变图片时,如果a的href属性有一个目标网址,但是点击又必须跳转到另外一张图,往往会最后跳转到目标网址,可以在onclick事件函数中加入ruturn false,阻止跳转到页面. ...