指针与数组的总结(优选7篇)

山崖发表网工作总结2024-01-28 08:35:0231

指针与数组的总结 第1篇

首先,从内存角度来理解数组:

从内存角度讲,数组变量就是一次分配多个变量,而且这多个变量在内存中的存储单元是依次相连接的。

例如,我们分开定义多个变量(int a,b,c,d;)和一次定义一个数组(int a[4];)这两种方法都定义了4个int型的变量,且这4个变量都是独立的成单个使用的。它们的不同点是,单独定义时a、b、c、d在内存中的地址不一定相连,但定义成数组后,数组中的4个元素地址肯定是依次相连的。

故数组中的多个变量虽然必须单独访问,但是因为它们的地址相连,因此可以用指针来操作。

对数组中几个关键符号(a a[0] &a &a[0])的理解:

以 int a[10] 为例

1. a 就是数组名

c语言规定不能整体操作数组,要独立到单个元素操作,所以 a 不能做左值。

a 做右值表示数组首元素的首地址(首地址就是起始地址,就是4个字节中最开始第一个字节的地址)。a 做右值等同于 &a[0]。

2. a[0] 表示数组的首元素

做左值时表示 a[0] 对应的内存空间(连续4个字节)

做右值时表示 a[0] 的值

3. &a 就是数组名 a 取地址

&a 不能做左值,做右值时表示整个数组的首地址。

4. &a[0] 就表示 a[0] 的首地址

当 &a[0] 做右值时等同于 &a 

现在我们定义有:int a[4]={1,2,3,4};   int *p=a;

则指针p就指向数组a首元素的首地址,(p+i)就是访问数组a中下标为 i 的元素的首地址,*(p+i)就是该元素的内容。也可以用 (数组名+偏移量) 即 (a+i) 来表示元素地址。

或者也可以采用 p[i] 来访问数组,p[i]==a[i]

指针数组与数组指针

1.指针数组

由指针变量组成的数组。定义:int *p[n];

若要将二维数组赋给一指针数组:

指针数组 p 的每个元素存放 数组 a 的每一行元素的首地址

2.数组指针(也称行指针)

指向数组的指针,即数组首元素地址的指针。定义 int (*p)[n];

若要指向一个二维数组:

指针与数组的总结 第2篇

      int a=1;     int * p=&a; //指针p指向了a的地址,p里保存了a的地址

         int p;    //这是一个普通的整型变量          int *p;   //首先从P 处开始,先与*结合,所以说明P 是一个指针,然后再与int 结合,说明指针所指向的内容的类型为int 型.所以P是一个返回整型数据的指针          int p[3];    //首先从P 处开始,先与[]结合,说明P 是一个数组,然后与int 结合,说明数组里的元素是整型的,所以P 是一个由整型数据组成的数组          int *p[3];   //首先从P 处开始,先与[]结合,因为其优先级比*高,所以P 是一个数组,然后再与*结合,说明数组里的元素是指针类型,然后再与int 结合,说明指针所指向的内容的类型是整型的,所以P 是一个由返回整型数据的指针所组成的数组         int (*p)[3];    //首先从P 处开始,先与*结合,说明P 是一个指针然后再与[]结合(与_()_这步可以忽略,只是为了改变优先级),说明指针所指向的内容是一个数组,然后再与int 结合,说明数组里的元素是整型的.所以P 是一个指向由整型数据组成的数组的指针         int **p;      //首先从P 开始,先与*结合,说是P 是一个指针,然后再与*结合,说明指针所指向的元素是指针,然后再与int 结合,说明该指针所指向的元素是整型数据.由于二级指针以及更高级的指针极少用在复杂的类型中,所以后面更复杂的类型我们就不考虑多级指针了,最多只考虑一级指针.

            解引用:    *p=10;

        <1>. int* p;    //指针类型是int* 

        <2>. char* p;   //指针类型是char*

        <3>. int** p;    //指针类型是int**

         <1>. int* p;   //指针指向的类型是 int

         <2>. char* p;   //指针指向的类型是char

         <3>. int** p;    //指针指向的类型是int*

指针与数组的总结 第3篇

       ***注意:“返回值类型”说明函数的返回类型,“(指针变量名 )”中的括号不能省,括号改变了运算符的优先级。若省略整体则成为一个函数说明,说明了一个返回的数据类型是指针的函数,后面的“形参列表”表示指针变量指向的函数所带的参数列表。例如:

int func(int x); /* 声明一个函数 */

int (*f) (int x); /* 声明一个函数指针 */

f=func; /* 将func函数的首地址赋给指针f */

或者使用下面的方法将函数地址赋给函数指针:

f = &func;

    1、定义一个函数指针;     2、将函数指针指向一个函数;     3、调用这个函数指针所指向的函数。

  

指针与数组的总结 第4篇

数组中的各元素在内存中是连续分布的,要想访问数组中某一元素,那么就必须知道其地址

在一维数组中,数组A的元素A[i]的地址&A[i]=A+L*i,其中A为数组的标识符(数组名),也可以用A来代表数组的首地址,L为数组A的数据类型,由此可见,对于一维数组,只需要知道数据类型大小和索引i,就可以知道A[i]的地址,从而就可以访问A[i]了,这也是为什么一维数组的定义可以不指定数组大小,也不会妨碍数组元素的访问。

二维数组,实际上也是一维数组,只不过这个一维数组的每个元素都是一个一维数组。因此,将二维数组的每一行看做一个元素,很容易可以知道二维数组中各元素在内存中是按行优先进行连续存储的,如定义数组A[3][4],那么它在内存中的存储情况如下:

由此也可得到二维数组中元素A[i][j]的地址为&A[i][j]=A+L*(C*i+j),其中A为二维数组A的标识符(数组名),也就是数组的首地址,L为数组元素的数据类型,C为二维数组的列数。由此可见,要知道二维数组中某一元素的地址,就必须知道数据类型大小以及二维数组的列数,这样最终才能实现对二维数组元素的访问,这也是为什么二维数组的定义必须指定列数。

指针与数组的总结 第5篇

建议:尽量避免使用指针和数组

指针和数组容易产生不可预料的错误。其中一部分是概念上的问题:指针用于低级操作,容易然生与繁琐细节相关的(book keeping)错误。其他错误则源于使用指针的语法规则,特别是声明指针的语法。

许多有用的程序都可不使用数组或指针实现,现代C++程序采用vector类型和迭代器取代一般的数组、采用string类型取代C风格字符串。

指针可能的取值

一个有效的指针必然是以下三种状态之一:保存一个特定对象的地址;指向某个对象后面的另一对象;或者是0值。若指针保存0值,表明它不指向任何对象。未初始化的指针是无效的,直到给该指针赋值后,才可使用它。

指针初始化和赋值操作的约束

对指针进行初始化或赋值只能使用以下四种类型的值:

(1)0值常量表达式。

(2)类型匹配的对象的地址。

(3)另一对象之后的下一地址。

(4)同类型的另一个有效指针。

把int型变量赋给指针是非法的,尽管此int型变量的值可能为0。

void*指针

C++提供了一种特殊的指针类型void*,它可以保存任何类型对象的地址:

----void*表明该指针与一地址值相关,但不清楚存储在此地址上的对象的类型。

----void*指针只支持几种有限的操作:与另一个指针进行比较;向函数传递void*指针或从函数返回void*指针;给另一个void*指针复制。

 ----不允许用void*指针操纵它所指向的对象。

一、解引用操作生成左值

二、关键概念:给指针赋值或通过指针进行赋值

对于初学指针者,给指针赋值和通过指针进行赋值这两种操作的差别确实让人费解。谨记区分的重要方法是:如果对左操作数进行解引用,则修改的是指针所指向的值;如果没有使用解引用操作,则修改的是指针本身的值。

三、指针和引用的比较

第一个区别在于引用总是指向某个对象:定义引用时没有初始化是错误的。第二个重要区别则是复制行为的差异:给引用赋值修改的是该引用所关联的对象的值,而并不是使引用与另一个对象关联。引用一经初始化,就始终指向同一个特定对象(这就是为什么引用必须在定义时初始化的原因)。

四、指向指针的指针

指针本身也是可用指针指向的内存对象。指针占用内存空间存放其值,因此指针的存储地址可存放在指针中。

五、C++还支持对这两个指针做减法操作:

结果是4,这两个指针所指向的元素间隔为4个对象。两个指针减法操作的结果是标准库类型ptrdiff_t的数据。与size_t类型一样,ptrdiff_t也是一种与机器相关的类型,在cstddef头文件中定义。size_t是unsigned类型,而ptrdiff_t则是signed_t整型。

允许在指针上加减0,使指针保持不变。如果一指针具有0值,则在该指针上加0仍然是合法的,结果得到另一个值为0的指针。也可以对两个空指针做减法操作,得到的结果仍是0。

六、解引用和指针算术操作之间的相互作用

在指针上加一个整型数值,其结果仍然是指针。允许在这个结果上直接进行解引用操作,而不必先把它赋给一个新指针:

加法操作两边用圆括号括起来是必要的。如果写为:

意味着对ia进行解引用,获得ia所指元素的值ia[0],然后加4。

七、计算数组的超出末端指针

C++允许计算数组或对象的超出末端的地址,但不允许对此地址进行解引用操作。而计算数组超出末端位置之后或数组首地址之前的地址都是不合法的。

可使用此超出末端指针的当做一个哨兵,如同在vector中使用的end变量一般,用于输出和遍历数组,这是一个好习惯

八、指针和const限定符

指向const对象的指针

const限定了cptr指针所指向的对象类型,而并非cptr本身。也就是说,cptr本身并不是const。

不能使用void*指针保存const对象的地址,而必须使用const void*类型的指针保存const对象的地址:

不能使用指向const对象的指针修改基础对象,然而如果该指针指向的是一个非const对象,可用其他方法修改其所指的对象。

九、const指针

C++语言还提供了const指针——本身的值不能修改:

指向const对象的const指针,既不能修改所指对象的值,也不允许修改指针的指向。

C风格字符串的标准库函数(要使用这些标准库函数,必须包含相应的C头文件:cstring)

strlen(s)strcmp(s1, s2)strcat(s1, s2)
strcpy(s1, s2)strncat(s1, s2, n) strncpy(s1, s2, n)

注意:这些标准库函数不会检查其字符串参数

永远不要忘记字符串结束符null,调用者必须确保目标字符串具有足够的大小

如果必须使用C风格字符串,则使用标准库函数strncat和strncpy比strcat和strcpy函数更安全

 对大部分的应用而言,使用标准库类型string,除了增强安全性外,效率也提高了,因此应该尽量避免使用C风格字符串。

指针与数组的总结 第6篇

一维数组指针的定义方式如下:

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

int *p=a;

这里定义了一个指针变量p,它指向一个整型变量,而a实际上也就是a的第一个元素a[0]的地址,因此p就指向了数组的第一个元素a[0]。 那么p+1等于什么呢?实际上,p+1在数值上也就等于a+1,因此,p+1其实就是a[1]的地址,p+i就是a[i]的地址,这样,就可以通过*(p+i)来访问a[i]的值了。如图所示:

由此可以得出,对于一维数组的数组指针p,数组名p实际上是指向数组第一个元素的指针,即p为int *类型,由于其指向int型数据,因此(p+i)就相当于在p的基础上偏移了i*sizeof(int)的地址大小,就等于数组第i个元素的地址(i=0,1,2....)。

指针与数组的总结 第7篇

在理解访问数组的指针之前,我们不得不先理解另一个问题:如果定义一个数组A,按前面所说,A就是数组第一个元素的首地址,那么A+1是什么意思呢?我在第一次遇到这个问题的时候,第一反应是A既然表示的是地址,那么A+1自然就是地址+1了呀!然而事实并非如此,我们先来做个测试如图所示:

根据测试可知,a+1并非就是a数值上加1,a+2也并非是a数值上加上2,他们实际上两两之间加的是4,即是sizeof(int),而*a=a[0]=1,*(a+1)=a[1]=2.....由此可以知道,a+i实际上就是a的第i个元素的地址,这与前面&A[i]的地址计算是相匹配的。

而对于二维数组来说,道理其实是一样的,不过二维数组的元素A[0]表示第一行,A[1]表示第二行......因此,二维数组中A是数组的首地址,也就是第0行A[0]的行首地址,A+1就是第1行A[1]的行首地址,.....,A+i就是第i行A[i]的行首地址了....

显示全文

注:本文部分文字与图片资源来自于网络,转载此文是出于传递更多信息之目的,若有来源标注错误或侵犯了您的合法权益,请立即后台留言通知我们,情况属实,我们会第一时间予以删除,并同时向您表示歉意

点击下载文档

文档为doc格式

发表评论

评论列表(7人评论 , 39人围观)

点击下载
本文文档