先看一下基本的形式,我们从这里起步!
--------------指针----------------
int a=10;
int *p=&a;
-------------指针的指针-----------
int b=20;
int *p=&b;
int **p2p=&p;
-------------简单数组-----------------
int c[10];//整数数组,含有10个整数元素
file://也就是说每一个元素都是整数
--------------指针数组--------------------
int *p[10];//指针数组,含有10个指针元素
file://也就是说每一个元素都是指针
--------------数组指针--------------------
int (*p)[10];//数组指针,这个指针可以用来指向
file://含有10个元素的整数数组
先看一段程序。
#include <iostream>
#include <typeinfo>
using namespace std;
int main()
{
int vInt=10;
int arr[2]={10,20};
int *p=&vInt;
int **p2p=&p;
int *parr[2]={&vInt,&vInt};
int (*p2arr)[2]=&arr;
cout<<"Declaration [int vInt=10] type=="<<typeid(vInt).name()<<endl;
cout<<"Declaration [arr[2]={10,20}] type=="<<typeid(arr).name()<<endl;
cout<<"Declaration [int *p=&vInt] type=="<<typeid(p).name()<<endl;
cout<<"Declaration [int **p2p=&p] type=="<<typeid(p2p).name()<<endl;
cout<<"Declaration [int *parr[2]={&vInt,&vInt}] type=="<<typeid(parr).name()<<endl;
cout<<"Declaration [int (*p2arr)[2]=&arr] type=="<<typeid(p2arr).name()<<endl;
return 0;
}
运行的结果如下:(我在前面加了行号#XX)
#01 Declaration [int vInt=10] type==int
#02 Declaration [arr[2]={10,20}] type==int *
#03 Declaration [int *p=&vInt] type==int *
#04 Declaration [int **p2p=&p] type==int * *
#05 Declaration [int *parr[2]={&vInt,&vInt}] type==int **
#06 Declaration [int (*p2arr)[2]=&arr] type==int (*)[2]
--------#02:数组------------
现在看#02,想到了什么没有呀?在编译器看来数组只是相对应类型的指针类型。
当我们把数组传递给函数作为参数的时候,传递的是指针,所以我们可以利用
参数来修改数组元素。这个转化是编译器自动完成的。
void f(int[]);
int a[2]={10,20};
f(a);//这行等价于编译器完成的函数转化f(int *p)
也就是说这里编译器自动完成了int[]类型到int *的转化,
注意是编译器完成的,也可以说是语言本身实现的,我们
对此只有接受的份了。
-------#05:指针数组---------------
指针数组的编译器内部表示也是对应类型的指针。
------#06:数组指针----------------
数组指针的编译器内部表示就是有一点特别了。
编译器(或者说是语言本身)有数组指针这个内部表示。
由于c++语言的类型严格检查的语言(当然还有一些是存在隐式类型转化的)
下面到底哪个是数组指针,哪个是指针数组呢:
A)
int *p1[10];
B)
int (*p2)[10];
“[]”的优先级比“*”要高。p1 先与“[]”结合,构成一个数组的定义,数组名为p1,int *修饰的是数组的内容,即数组的每个元素。那现在我们清楚,这是一个数组,其包含10 个指向int 类型数据的指针,即指针数组。至于p2 就更好理解了,在这里“()”的优先级比“[]”高,“*”号和p2 构成一个指针的定义,指针变量名为p2,int 修饰的是数组的内容,即数组的每个元素。数组在这里并没有名字,是个匿名数组。那现在我们清楚p2 是一个指针,它指向一个包含10 个int 类型数据的数组,即数组指针。
int (*)[10] p2-----也许应该这么定义数组指针
这里有个有意思的话题值得探讨一下:平时我们定义指针不都是在数据类型后面加上指针变量名么?这个指针p2 的定义怎么不是按照这个语法来定义的呢?也许我们应该这样来定义p2:
int (*)[10] p2;
int (*)[10]是指针类型,p2 是指针变量。这样看起来的确不错,不过就是样子有些别扭。其实数组指针的原型确实就是这样子的,只不过为了方便与好看把指针变量p2 前移了而已。你私下完全可以这么理解这点。
实例:
通过上面的分析,相信你已经明白数组和指针的访问方式了,下面再看这个例子:
main()
{
int a[5]={1,2,3,4,5};
int *ptr=(int *)(&a+1);
printf("%d,%d",*(a+1),*(ptr-1));
}
打印出来的值为多少呢? 这里主要是考查关于指针加减操作的理解。
对指针进行加1 操作,得到的是下一个元素的地址,而不是原有地址值直接加1。所以,一个类型为T 的指针的移动,以sizeof(T) 为移动单位。因此,对上题来说,a 是一个一维数组,数组中有5 个元素; ptr 是一个int 型的指针。
&a + 1: 取数组a 的首地址,该地址的值加上sizeof(a) 的值,即&a + 5*sizeof(int),也就是下一个数组的首地址,显然当前指针已经越过了数组的界限。
(int *)(&a+1): 则是把上一步计算出来的地址,强制转换为int * 类型,赋值给ptr。
*(a+1): a,&a 的值是一样的,但意思不一样,a 是数组首元素的首地址,也就是a[0]的首地址,&a 是数组的首地址,a+1 是数组下一元素的首地址,即a[1]的首地址,&a+1 是下一个数组的首地址。所以输出2*(ptr-1): 因为ptr 是指向a[5],并且ptr 是int * 类型,所以*(ptr-1) 是指向a[4] ,输出5。
发表评论
-
set容器的反向迭代器
2013-05-02 16:56 3742#include <iostream> #in ... -
对于CRITICAL_SECTION用法的介绍和理解[转]
2013-04-08 11:50 2181很多人对CRITICAL_SECTION ... -
二维数组知识
2012-09-15 17:20 816二维数组和指针⑴ 用 ... -
Realloc的使用
2012-08-14 11:04 829realloc 用过很多次了。 ... -
extern C的由来
2012-08-09 10:14 695时常在cpp的代码之中看到这样的代码: #ifdef ... -
C++类对象的创建过程
2012-07-26 16:02 938分配空间(Allocation) ... -
静态数据成员和静态成员函数
2012-07-26 15:04 3110静态类成员包括静态数据成员和静态函数成员两部分。 与 ... -
复制构造函数(拷贝构造函数)以及深浅拷贝
2012-07-25 22:39 1428对于普通对象而言复制是很简单的,一般是将变量或者常量赋值给某 ... -
cin、cin.get、cin.getline()、getline()、gets()的用法【转】
2012-07-24 20:05 831学C++的时候,这几个输入函数弄的有点迷糊;这里做个小结,为了 ... -
编程笔记(07-24)
2012-07-24 15:15 6671 #include < stdio.h ... -
堆、栈解疑
2012-07-12 21:53 584一、预备知识—程序的内存分配 一个由C/C++编译的程序 ... -
指针和内存分配的深度理解
2012-07-12 18:57 1031一 :关于指针和堆的内存分配 先来介绍一下指针: 指针一种 ... -
const指针和指向const的指针
2012-07-12 10:30 2119指向const对象的指针 ... -
typedef的学习
2012-07-11 15:03 738typedef,顾名思义,为“类型定义”,可以解释为:将一种数 ... -
函数指针和指针函数
2012-07-11 11:21 594【函数指针】 ... -
Define学习
2012-07-11 10:12 1073宏替换是C/C++系列语言的技术特色,C/C++语言提 ... -
sizeof 深研
2012-07-11 09:39 6671、什么是sizeof 首先看一下sizeof ... -
内存对齐问题
2012-07-10 22:35 10961.内存数据对齐的原因: 无论如何,为了提高程序的性 ... -
指针深究
2012-07-09 21:55 594在说指向指针的指针之前,不得不说指向变量的指针。先看如下示例: ... -
C语言文件使用方式详解
2012-07-04 10:23 768文件的打开(fopen函数) f ...
相关推荐
数组指针和指针数组的区别 在 C 语言中,数组指针和指针数组是两个容易混淆的概念,但它们之间有着巨大的区别。本文将详细讲解数组指针和指针数组的定义、内存布局、区别,并通过实例代码加深读者的理解。 一、...
数组指针和指针数组
数组指针和指针数组
C51单片机C语言编程数组指针和指针数组应用 本文档介绍了C51单片机C语言编程中的数组指针和指针数组应用。在指针变量中存放一个数组或一个函数的首地址可以使程序的概念十分清楚,程序本身也精练,高效。 数组指针...
关于数组指针和指向数组指针的指针及其new的一些个人理解及其小例子,详细可以参见我的CSDN博客中的文章http://blog.csdn.net/shizhixin/article/details/7050592
通过理解指针数组、数组指针和二级指针,我们可以更灵活地操控内存,提高代码的效率和灵活性。这些概念对于理解C语言的底层机制和编写高效程序至关重要。在实际编程中,要特别注意指针的生命周期管理,避免内存泄漏...
### 彻底理解指针,指针数组和数组指针,指针函数和函数指针 #### 一、基础知识 在计算机编程中,指针是一个非常重要的概念,尤其是在C/C++这样的语言中更是如此。简单来说,指针是一种变量,但它存储的不是普通的...
在C语言中,指针和数组是两种非常重要的数据结构,它们可以...以上内容详细阐述了C语言中数组指针和指针数组的概念,以及如何通过指针操作数组,包括一维数组和多维数组。理解这些概念对于编写高效的C程序至关重要。
本文旨在澄清关于数组名是否等同于指针这一常见的误区,并通过具体的代码示例来深入探讨数组和指针之间的关系及其差异。 #### 二、数组与指针的基本概念 1. **数组**: - 数组是一系列相同类型的数据项的集合。 ...
数组的指针和指向数组的指针变量 数组的指针和指向数组的指针变量是编程语言中一个重要的概念。数组的指针是指向数组在内存中的起始地址,而指向数组的指针变量是指向数组元素的指针变量。 概念: * 数组的指针:...
### 指针数组与数组指针的概念及区别 在计算机编程中,特别是C语言及其衍生语言中,指针是一个非常重要的概念。它允许程序员直接访问内存地址,并对其进行操作。当我们深入探讨指针时,会遇到两个看似相似但实际上...
指针数组与数组指针是两种不同的数据结构概念,...通过深入理解和掌握指针数组与数组指针,我们可以在C语言编程中更高效地处理数据,实现复杂的数据结构操作。同时,也能够更安全地使用指针,避免内存泄漏等常见错误。
首先,介绍了C语言中数组和指针的概念,然后讨论了数组指针在汇编语言指令系统寻址方式中的应用和转换。 在C语言中,数组是一个重要的数据结构,它可以存储多个相同类型的数据。数组可以分解为多个数组元素,这些...
本文档主要讲解了 C++ 编程语言中数组指针的四个实践题目,每个题目都包含了详细的代码实现和输出结果。下面是对每个题目的详细解释: 数组指针 01:逆序输出从键盘输入 n 个整数(n),存放在一个一维数组中,逆序...
在学习“指针数组”和“数组指针”的概念之前,我们首先需要理解什么是“指针”。指针是一种数据类型,用于存储内存地址。在C语言中,指针变量的类型决定了它可以指向的数据类型。 - **指针的类型**:`char*`, `int...
### 基于数组指针实现二维数组中最小值所在行的查找与显示程序 #### 知识点一:理解数组指针与指针数组的区别 在C语言中,数组指针与指针数组有着本质的区别,它们在内存中的表示方式、使用场景以及功能上都存在...
需要注意的是,虽然在很多情况下数组名可以被视为指向数组首元素的指针,但数组和指针并不完全等价。数组名是一个常量指针,不能被重新赋值,而指针变量则可以。此外,数组类型和指针类型在某些情况下会有不同的行为...