如何透彻理解C语言中指针的概念

合集下载

C语言中的指针指什么

C语言中的指针指什么

C语言中的指针指什么指针概念指针是一个变量,该变量的数值是地址,或者说,指针是一个数据对象。

类似于,int 类型变量的数值是整数。

与指针相关的运算符间接运算符:*ptr 指向 bath,ptr = &bath。

获取 bath 中存放的数值,val = * ptr。

上面两句语句等价于 val = bath。

地址运算符:&后跟一个变量名时,& 给出该变量的地址。

指针声明int * pi;int 表明被指向的变量的类型是整型,* 表示该变量是一个指针。

pi 所指向的值(*pi)是 int 类型,pi 的类型是“指向 int 的指针”。

* 和指针名之间的空格是可选的。

指针的输出格式是 %p。

使用指针在函数间通信结合PHP中函数的引用赋值来理解。

变量的值在函数中改变还是全局改变。

指针和数组概念在 C 中,对一个指针加 1 的结果是对该指针增加 1 个存储单元(storage unit)。

对数组而言,地址会增加到下一个元素的地址,而不是下一个字节。

归纳如下:指针的数值就是它所指向的对象的地址。

对于包含多个字节的数据类型,对象的地址通常是指其首字节的地址。

在指针前运用运算符 * 可以得到该指针所指向的对象的数值。

对指针加1,等价于对指针的值加上它所指向的对象的字节大小。

函数、数组和指针声明数组参量下面的四种原型都是等价的int sum(int *ar, int n);int sum(int *, int);int sum(int ar[], int n);int sum(int [], int);定义函数时,下面两种形式等价int sum(int * ar, int n){}int sum(int ar[], int n){}声明形式参量时,int *ar 和 int ar[] 都表示 ar 是指向 int 的指针。

sizeof 求变量、指针、数组大小。

使用指针参数使用数组形参的.函数需要知道数组的起点和终点。

c语言指针的定义

c语言指针的定义

c语言指针的定义C语言中,指针是一个非常重要的概念。

所谓指针,就是指向内存中某个变量的地址的变量。

定义一个指针变量时,需要使用“*”符号表示这是一个指针变量。

例如:int*p;这个定义表示变量p是一个整型指针变量。

指针变量可以指向任何类型的数据,包括基本数据类型、数组、结构体等。

指针的使用需要注意以下几点:1.操作指针变量时,需要使用“&”符号获取变量的地址,例如:int a=10;int*p=&a;这个例子中,p指向了变量a的地址。

2.操作指针变量时,需要使用“*”符号获取指针指向的值,例如:int a=10;int*p=&a;printf("%d",*p);这个例子中,使用“*p”获取了指针p所指向的变量a的值,并将其打印出来。

3.指针变量可以通过赋值操作改变所指向的变量,例如:int a=10;int b=20;int*p=&a;*p=b;这个例子中,通过将指针p指向变量b的地址,将变量a的值改变为了20。

4.指针变量可以作为函数参数传递,通过指针可以在函数内部修改变量的值,例如:void add(int*a,int b){*a+=b;}int main(){int a=10;add(&a,5);printf("%d",a);return0;}这个例子中,通过指针变量将变量a的地址传递给函数add,在函数内部修改了变量a的值。

总之,指针是一个非常重要的概念,在C语言中广泛应用于各类程序中。

熟练掌握指针的使用方法,是每个C语言程序员的必备技能。

浅谈C语言中指针的概念及基本应用规律

浅谈C语言中指针的概念及基本应用规律
分地 表 现 自己 。
( 1 ) 定义指针后, 必须将其初始 化。 可以用做给指针变 量初
始化 的有变量 的地 址, 另一个指针变量 , 数 组名 , 函数名等 。 需
语句不起作用。 此时, s t r 手 旨 向的存储区里是什么? 我们不知道。
要注意的是动态 内存分配 时, 使用之前将其初始化为N U L L 。 指针在 定义之后, 如果没有 明确 赋值, 那么和其他 变量类 似, 其 内部 的地 址值 是随机 的。 此时指针指 向的空 间中的数据 意义是不可预 测的, 一般 成为野指针。 我们知道在c 语言 中, 指
r e e 或d e l e t e 释放该 内存块 , 否则 , 这块 内存 就不能被 量也必 须为指针, 且 应与返 回值的类 型相同。 指针变 量可 以指 的调用f 再 次使用 , 我们就 说这块 内存泄漏 了。 使 用指针 时, 在赋值 等 向整型变量、 字符 串变 量、 也可以指 向函数 的入 口地址和指针为
函数调用结束后系统会 自动收回 内存 。 的不 同是, 指针数组在指 针的数量 上有所 改变 , 它 由一 个指针 分配局部动态 变量等 , 全局数据 区存放的是静态和全局变量 , 随着程 序的消亡而 自动 演 变到一组同类 指针。
一般 我们 常说的内存 泄漏是指堆 内存 的泄 漏。 堆 ( 2 ) 指针 函数与函数 指针。 指 针函数 是 返回值 为指 针 的函 收收 回内存。 大小任 意的( 内存块的大小可以 数, 指针 函数 打破 了其它高级 语言中的指针、 数组不能作为返 内存 是指 程序从堆 区中分配的,
写程序还是有很大帮助的。 笔者从几个方面来剖析指针 的本质, 并着重围绕指针的一个重要应用一一动态分配内存来谈谈如何回避常见错

c语言指针详细讲解

c语言指针详细讲解

c语言指针详细讲解
C 语言中指针是非常强大的概念,它允许程序直接访问内存中的数据。

指针在 C 语言中最初是被用于解决内存分配问题而提出的,随着 C 语言的发展,指针也变得愈发重要。

指针的本质是一个存储变量地址的变量。

在 C 语言中,指针通常用符号&来表示,例如&x 表示的是 x 变量的地址。

指针变量存储的是一个内存地址,当程序读取指针变量时,它会读取该地址中存储的数据。

C 语言中可以使用指针进行高效的内存操作。

例如,当程序需要对一个数组元素进行修改时,可以直接用指针修改该元素的值,而不必修改数组名本身。

另外,指针还可以用于动态分配内存,这是 C 语言中一个重要的特性。

指针的使用方法比较灵活,但也需要小心使用。

如果不小心处理指针,可能会导致未知的错误。

例如,当指针指向的内存空间被释放后,程序试图访问该内存空间时可能会导致未定义的行为。

因此,在C 语言中,指针的使用需要更加谨慎。

C 语言中指针是一个非常重要和强大的概念,掌握指针的使用方法可以让程序员写出更加高效和安全的代码。

c语言 指针的指针 用法详解

c语言 指针的指针 用法详解

c语言指针的指针用法详解在C语言中,指针是非常重要的一种数据类型。

而指针的指针是指指向指针变量的指针。

它在C语言中也是非常重要的一种数据类型,经常用于动态内存分配和函数传递参数等方面。

下面,我们来详细介绍一下指针的指针在C语言中的用法。

一、指针的基本概念在C语言中,指针是一个变量,用来表示另一个变量的内存地址。

指针变量可以存储任何数据类型的地址,包括整型、字符型、浮点型等。

使用指针可以实现动态内存分配、函数传递参数等功能。

二、指针的指针的概念指针的指针是指指向指针变量的指针。

它的定义方式如下:```int **p;```其中,p是一个指向指针的指针变量,它可以指向一个指针变量的地址。

三、指针的指针的用法指针的指针在C语言中有很多用途,下面列举几个比较常见的用法。

1.动态内存分配在C语言中,可以使用malloc函数动态分配内存,该函数返回的是一个指向分配内存的首地址的指针。

而在一些情况下,需要动态分配二维数组或者指针数组,这时就需要使用指针的指针了。

例如:```int **p;int i,j;p=(int **)malloc(sizeof(int*)*3);//分配3个指向int类型指针的指针变量for(i=0;i<3;i++){p[i]=(int*)malloc(sizeof(int)*4);//分配4个int类型的变量}for(i=0;i<3;i++){for(j=0;j<4;j++){p[i][j]=i*j;//为p[i][j]赋值}}```上述代码中,先使用malloc函数分配3个指向int类型指针的变量,然后再用循环分别为这3个变量分配4个int类型的变量。

最后,再使用嵌套循环为二维数组赋值。

2.函数传递参数在C语言中,函数可以通过指针传递参数。

指针的指针也可以用于函数传递参数,可以使函数返回多个值。

例如:```void fun(int **p){*p=(int*)malloc(sizeof(int)*4);//为指针p分配4个int类型的变量(*p)[0]=10;(*p)[1]=20;(*p)[2]=30;(*p)[3]=40;}int main(){int *p;fun(&p);//传递p的地址printf("%d %d %d %d\n",p[0],p[1],p[2],p[3]);free(p);//释放内存return 0;}```上述代码中,定义了一个指针类型的函数fun,在函数中通过指针的指针为指针p分配4个int类型的变量,并为这4个变量赋值。

C指针详解(经典,非常详细)

C指针详解(经典,非常详细)

总结课:让你不再害怕指针指针所具有的四个要素:指针的类型,指针所指向的类型,指针指向的内存区,指针自身占据的内存。

0前言:复杂类型说明要了解指针,多多少少会出现一些比较复杂的类型,所以我先介绍一下如何完全理解一个复杂类型,要理解复杂类型其实很简单,一个类型里会出现很多运算符,他们也像普通的表达式一样,有优先级,其优先级和运算优先级一样,所以我总结了一下其原则:从变量名处起,根据运算符优先级结合,一步一步分析.下面让我们先从简单的类型开始慢慢分析吧: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 结合,说明该指针所指向的元素是整//型数据.由于二级指针以及更高级的指针极少用//在复杂的类型中,所以后面更复杂的类型我们就//不考虑多级指针了,最多只考虑一级指针.int p(int);//从P处起,先与()结合,说明P是一个函数,然后进入//()里分析,说明该函数有一个整型变量的参数//然后再与外面的int结合,说明函数的返回值是//一个整型数据int(*p)(int);//从P处开始,先与指针结合,说明P是一个指针,然后与//()结合,说明指针指向的是一个函数,然后再与()里的//int结合,说明函数有一个int型的参数,再与最外层的//int结合,说明函数的返回类型是整型,所以P是一个指//向有一个整型参数且返回类型为整型的函数的指针int*(*p(int))[3];//可以先跳过,不看这个类型,过于复杂//从P开始,先与()结合,说明P是一个函数,然后进//入()里面,与int结合,说明函数有一个整型变量//参数,然后再与外面的*结合,说明函数返回的是//一个指针,,然后到最外面一层,先与[]结合,说明//返回的指针指向的是一个数组,然后再与*结合,说//明数组里的元素是指针,然后再与int结合,说明指//针指向的内容是整型数据.所以P是一个参数为一个//整数据且返回一个指向由整型指针变量组成的数组//的指针变量的函数.说到这里也就差不多了,我们的任务也就这么多,理解了这几个类型,其它的类型对我们来说也是小菜了,不过我们一般不会用太复杂的类型,那样会大大减小程序的可读性,请慎用,这上面的几种类型已经足够我们用了.1、细说指针指针是一个特殊的变量,它里面存储的数值被解释成为内存里的一个地址。

c语言指针教学中的知识点分析与总结

c语言指针教学中的知识点分析与总结

c语言指针教学中的知识点分析与总结c语言指针教学中的知识点分析与总结本文对c语言指针的教学进行了探讨和总结。

要想真正的掌握c 语言的指针,首先必须要对它有全面深刻的认识。

因为它是c语言的基础,只有将指针的知识学好,才能够更好地学习后续的课程。

下面小编给大家介绍一下关于c语言指针的知识。

一、 c语言中指针的定义指针是一种特殊的数据类型,也称为引用类型。

所谓指针就是指向一个地址的变量,例如: int a[10];二、变量指针及指针变量1.1 c语言中的变量。

变量是存储在计算机中的二进制数值,当我们需要使用时,必须创建一个变量并赋予它相应的值,然后将变量的地址传递给外部的一个或多个对象,这样外部对象通过访问内部变量来使用其中存储的信息,而且可以保证外部对象不会越界。

1.2指针变量是变量的一种特殊形式,指针变量在内存中占有一块区域,可以指向一个地址,这个地址的值是这个变量所代表的值,这样方便变量间的传递。

例如: char *a[10];2.1指针操作符2.2指针数组,它的作用和一维数组相同,即具有一维数组的特点,也具有二维数组的特点,三者最明显的区别就是二维数组中元素个数是固定的,而一维数组中元素个数是可变的。

2.3指针的运算规则。

在指针变量的操作中,要遵循以下运算规则:原地址→指针地址。

例如: char * a[10]; 2.4 c语言中的const指针常量是一种特殊的指针常量, const不是一种变量的标准类型,它专门用于指向一个const指针。

2.3指针的运算规则。

在指针变量的操作中,要遵循以下运算规则:原地址→指针地址。

例如: char *a[10];2.4指针的定义与使用:所谓指针就是指向一个地址的变量,例如: int a[10]; 2.4指针的定义与使用: pointer, pointer-pointer,and-and-and。

所以,当我们在一个字符串中出现pointer,pointer-pointer, and-and-and的时候,就表示它指向一个地址。

c语言中的指针详解

c语言中的指针详解

c语言中的指针详解在C语言中,指针是一种特殊的变量类型,它存储了一个变量的内存地址。

通过指针,我们可以间接访问和修改内存中的数据,这对于一些需要动态分配内存的操作非常有用。

以下是关于C语言指针的一些详细解释:1. 定义指针:使用"*"符号来定义指针变量。

例如,int* ptr; 定义了一个指向整型变量的指针 ptr。

2. 取址操作符(&):取地址操作符(&)用于获取变量的内存地址。

例如,&a 返回变量 a 的地址。

3. 解引用操作符(*):解引用操作符(*)用于访问指针所指向的变量的值。

例如,*ptr 返回指针 ptr 所指向的整型变量的值。

4. 动态内存分配:可以使用相关的库函数(如malloc和calloc)在运行时动态分配内存。

分配的内存可以通过指针来访问和使用,并且在使用完后应该使用free函数将其释放。

5. 空指针:空指针是一个特殊的指针值,表示指针不指向任何有效的内存地址。

可以将指针初始化为NULL来表示空指针。

6. 指针和数组:指针和数组在C语言中有密切的关系。

可以通过指针来访问数组元素,并且可以使用指针进行指针算术运算来遍历数组。

7. 传递指针给函数:可以将指针作为函数参数传递,以便在函数内部修改实际参数的值。

这种传递方式可以避免拷贝大量的数据,提高程序的效率。

8. 指针和字符串:字符串在C语言中实际上是以字符数组的形式表示的。

可以使用指针来访问和操作字符串。

需要注意的是,指针在使用时需要小心,因为不正确的操作可能导致程序崩溃或产生不可预料的结果。

对于初学者来说,理解指针的概念和使用方法可能需要一些时间和练习。

c语言中什么是指针

c语言中什么是指针

c语言中什么是指针指针一般指向一个函数或一个变量。

在使用一个指针时,一个程序既可以直接使用这个指针所储存的内存地址,又可以使用这个地址里储存的函数的值。

在计算机语言中,由于通过地址能找到所需的变量单元,可以说,地址指向该变量单元。

因此,将地址形象化的称为“指针”。

意思是通过它能找到以它为地址的内存单元。

1:指针是一个地址,指向的是个类型:我们知道,c语言中的类型有int,char,bool(这个不常用),一般我们使用int,char就可以满足一般的类型需求的,如果对于变量的长度过大,就是用long ,float,double,关于各个类型使用的的长度问题,可以使用sizeof(int)或者sizeof(long)来查看各个类型,在系统中的小。

而指针就是一个8个字节(64系统)。

2:指针指向的是地址,地址指向的是内容:我们需要一个变量,来存储地址,这个变量的值是地址,但是我们可以通过修改变量的值,来不断的改变地址,但是,我们如果需要改变该个地址的值的话,就需要,对地址的值进行修改,而不改变地址。

int a = 10;int *p ;p = &a;*p =11;a=?这里我们看到,p 是一个变量,我们使用p来存储变量a的地址,这是,我们使用*p对于这个变量进行赋值,那么a的值最后,是多少呢,结果是11,因为我们使用*p赋值,就相当于a=11,赋值效果一样的。

3:指针的指针,是面对于指针的变量:我们说,指针的指针的时候,就有点不清楚了,到底怎么区分指针和指针的指针呢。

char *p;char **pr;pr = &p;我们这样看就清楚了一点,char *(*pr); *pr是一个存储的值为指针的变量,pr就是存储上个变量地址的变量。

整合起来就是,pr是一个存储的值为指针的地址的变量。

这样,我们就基本,对于指针有一个直接的了解了。

如何透彻理解C语言中指针的概念

如何透彻理解C语言中指针的概念

如何透彻理解C语言中指针的概念强大的指针功能是C语言区别于众多高级语言的一个重要特征。

C语言指针的功能强大,使用灵活多变,可以有效地表示复杂的数据结构、动态分配内存、高效地使用数组和字符串、使得调用函数时得到多个返回值。

而它的应用远不限于此。

初学者对于指针的概念总是感到无所适从,有时觉得“自己懂了,为什么编译器就是不懂呢”,常有茫然和无助的感觉。

学好指针的关键在于深入了解内存地址的空间可以理解为一个一维线性空间,内存的编址和寻址方法,以及指针在使用上的一些规定。

事实上,指针就是方便我们对内存地址直接进行操作的,是为程序员服务的,我们只要抓住指针想要帮助我们解决什么问题这个核心,就可以轻松地理解它的工作原理。

什么是指针,指针有什么作用指针就是指向一个特定内存地址的一个变量。

简化了的内存空间模型是按照从0到某一个数(比如1048575=1M-1)的一维线性空间,其中的每一个数对应一个存储单元,即1个字节。

指针有两个属性:指向性和偏移性。

指向性指的是指针一定要有一个确定的指向,偏移性则是体现指针重要应用的方面,即指针可以按程序员的要求向前或向后偏移。

指针的应用往往与数组联系在一起,为了方便说明问题,不妨从数组开始解释指针的偏移。

数组就是许多的变量,它的一个重要特征就是在内存空间中连续地存放,而且是按下标顺序存放。

比如我们定义一个有100个变量的一维整型数组,它一定从内存的某一个存储单元开始按数组下标顺序存放,连续占用100*4=400字节。

当我们定义一个数组时,系统就会自动为它分配一个指针,这个指针指向数组的首地址。

(在本文剩余部分的论述中,不加区分地使用“指向数组的首地址”与“指向数组的第一个元素”这两种说法,事实上这两种说法也是一致的。

)为了让系统了解每一次指针偏移的单位,也为了方便程序员进行指针偏移(让程序员记住一个整形变量占用4字节,一个字符型变量占用1字节……等等是很麻烦的),不用每次去计算要偏移多少个字节,C语言引入了指针的基类型的概念。

c语言指针的用法

c语言指针的用法

c语言指针的用法c语言是一种高级编程语言,它可以直接操作内存中的数据。

指针是c语言中一种特殊的变量,它可以存储另一个变量的地址,也就是内存中的位置。

通过指针,我们可以间接地访问或修改内存中的数据,从而实现更高效和灵活的编程。

本文将介绍c语言指针的基本概念、定义和初始化、运算和应用,以及一些常见的错误和注意事项。

希望本文能够帮助你掌握c语言指针的用法,提高你的编程水平。

指针的基本概念指针是一种数据类型,它可以存储一个地址值,也就是内存中某个位置的编号。

每个变量在内存中都有一个唯一的地址,我们可以用指针来记录这个地址,然后通过这个地址来访问或修改变量的值。

例如,假设有一个整型变量a,它的值为10,它在内存中的地址为1000(为了简化,我们假设地址是十进制数)。

我们可以定义一个指向整型的指针p,并把a的地址赋给p,如下所示:int a =10; // 定义一个整型变量a,赋值为10int*p; // 定义一个指向整型的指针pp =&a; // 把a的地址赋给p这里,&a表示取a的地址,也就是1000。

p = &a表示把1000赋给p,也就是让p指向a。

从图中可以看出,p和a是两个不同的变量,它们占用不同的内存空间。

p存储了a的地址,也就是1000。

我们可以通过p 来间接地访问或修改a的值。

指针的定义和初始化指针是一种数据类型,它需要在使用前进行定义和初始化。

定义指针时,需要指定它所指向的变量的类型。

初始化指针时,需要给它赋一个有效的地址值。

定义指针的一般格式为:type *pointer_name;其中,type表示指针所指向的变量的类型,如int、char、float等;pointer_name表示指针的名称,如p、q、ptr等;*表示这是一个指针类型。

例如:int*p; // 定义一个指向整型的指针pchar*q; // 定义一个指向字符型的指针qfloat*ptr; // 定义一个指向浮点型的指针ptr注意,在定义多个指针时,每个指针前都要加*号,不能省略。

C语言难点及分析

C语言难点及分析

C语言难点及分析C语言是一种贴近硬件的高级编程语言,常用于嵌入式系统、操作系统和底层开发等领域。

虽然C语言相对于其他编程语言来说比较简单,但仍有一些难点需要注意和分析。

一、指针的理解和使用指针是C语言中的一个重要概念,也是相对较难的部分之一、学习指针的难点主要在于其抽象和概念的理解,以及指针的使用方式。

指针可以理解为内存地址,它指向存储单元的位置。

通过指针可以直接操作内存中的数据,使得程序更加高效灵活。

但是,指针的错误使用可能导致程序崩溃或产生未知的结果,因此需要特别小心。

指针的难点主要表现在以下几个方面:1.指针和变量的关系理解:指针和变量之间是一种间接关系,指针是存储变量地址的变量。

2.指针的声明和初始化:指针变量的声明和初始化需要注意语法和语义的细节,如指针的类型和指针所指向的数据类型。

3.指针的运算和使用:指针可以进行递增和递减运算,也可以用于数组、函数和结构体等复杂数据结构的操作。

二、内存管理C语言中,需要手动进行内存的申请和释放,这是相对于高级语言的一种特殊机制。

内存的申请和释放需要遵循一定的规则,否则可能会引发内存泄漏或者野指针的问题。

内存管理的难点主要表现在以下几个方面:1. 动态内存分配:动态内存分配是指在程序运行过程中根据需要申请和释放内存。

C语言中提供了动态内存分配的函数,如malloc、calloc和realloc等,但需要特别注意内存的申请大小和合理的内存释放。

2.内存泄漏和野指针:内存泄漏是指程序申请到内存后,没有进行正确释放导致内存一直占用。

而野指针是指指向无效内存地址的指针,可能会引发程序崩溃或产生未知的错误结果。

三、字符串的处理C语言中,字符串是以字符数组的形式来表示的。

字符串的处理涉及到字符的操作、字符串的拼接和比较、字符串的查找和替换等功能,对于初学者来说可能比较困难。

字符串处理的难点主要表现在以下几个方面:1.字符串数组和字符数组的区别:字符串必须以'\0'结尾,表示字符串的结束符,而字符数组可以不需要。

C语言教学中指针概念解析及注意问题

C语言教学中指针概念解析及注意问题
放 任 存 储 器 中 。 一 把 一 个 字 节 空 间 称 为 一 般 个内 存单 元 ,为 了正确 访 问这 些 内 存单 元 , 单 元 的 编 号 即 可 准 确 的 找 到 该 内 存 单 元 ,我 们 把 内存 单 元 的 编 号叫 地 址 。 通 常 是 一 个 字 vi o d数 据 类 型 是 一 种 很 重 要 的 数 据 类 型 。v i od的 意 思 就 是 “ 值 ” 或 “ 类 型 ” 无 无 。 针 ”。 之 所 以 有 这 样 的 名 字 是 因 为 使 用 vi o d指 针 可 以 很 容 易 地 把 v i o d指 针 转 换 成
者的一道难关 。
接输 出。 须在 输 出 前加 上 的 地 址 并 没 有 变 化 , 只是 类 型 变 了 , 比 如 在 针 的 位 置 。 执行p ++的 时 候 , 原 来 是 增 加 4个 字 节 (2 3 2. 内存 泄漏 3 位 i ) 而 转 换 之 后 便 成 了 增 加 1 字 节 nt , 个
必 须 为 每 个 内 存 单 元 编 上 号 , 根 据 某 个 内 仔 vod指 针 一 般 称 为 “ 用 指 针 ” 或 “ 指 i 通 泛
的意 义 :( )避 免 了内 存空 间 的浪 费 ; ( ) 1 2 防 止 了 内 存 泄 漏 。 产 生 内 存 泄 漏 是 由 于 如 果 没 有 及时 释 放掉 指 针所 占用 的 内存 空阈 , 而 住 下 次 使 用 这 个 指 针 时 又 给 这 个 指 针 分 配 了 内 存 空 间 , 这 样 的 次 数 一 多 , 内 存 空 间就 慢 慢 被 消耗 掉 了 ,所 以 形 象 地 称这 种 现 象 为 内存 泄 漏 ,如 下 面 这 样 一个 程 序 :

C语言指针知识点总结

C语言指针知识点总结

C语⾔指针知识点总结1.指针的使⽤和本质分析(1)初学指针使⽤注意事项1)指针⼀定要初始化,否则容易产⽣野指针(后⾯会详细说明);2)指针只保存同类型变量的地址,不同类型指针也不要相互赋值;3)只有当两个指针指向同⼀个数组中的元素时,才能进⾏指针间的运算和⽐较操作;4)指针只能进⾏减法运算,结果为同⼀个数组中所指元素的下表差值。

(2)指针的本质分析①指针是变量,指针*的意义:1)在声明时,*号表⽰所声明的变量为指针。

例如:int n = 1; int* p = &n;这⾥,变量p保存着n的地址,即p<—>&n,*p<—>n2)在使⽤时,*号表⽰取指针所指向变量的地址值。

例如:int m = *p;②如果⼀个函数需要改变实参的值,则需要使⽤指针作为函数参数(传址调⽤),如果函数的参数数据类型很复杂,可使⽤指针代替。

最常见的就是交换变量函数void swap(int* a, int* b)③指针运算符*和操作运算符的优先级相同例如:int m = *p++;等价于:int m= *p; p++;2.指针和数组(1)指针、数组、数组名如果存在⼀个数组 int m[3] = {1,2,3};定义指针变量p,int *p = m(这⾥m的类型为int*,&a[0]==>int*)这⾥,其中,&m为数组的地址,m为数组0元素的地址,两者相等,但意义不同,例如:m+1 = (unsigned int)m + sizeof(*m)&m+1= (unsigned int)(&m) + sizeof(*&m)= (unsigned int)(&m) + sizeof(m)m+1表⽰数组的第1号元素,&m+1指向数组a的下⼀个地址,即数组元素“3”之后的地址。

等价操作:m[i]←→*(m+i)←→*(i+m)←→i[m]←→*(p+i)←→p[i]实例测试如下:1 #include<stdio.h>23int main()4 {5int m[3] = { 1,2,3 };6int *p = m;78 printf(" &m = %p\n", &m);9 printf(" m = %p\n", m);10 printf("\n");1112 printf(" m+1 = %p\n", m + 1);13 printf(" &m[2] = %p\n", &m[2]);14 printf(" &m+1 = %p\n", &m + 1);15 printf("\n");1617 printf(" m[1] = %d\n", m[1]);18 printf(" *(m+1) = %d\n", *(m + 1));19 printf(" *(1+m) = %d\n", *(1 + m));20 printf(" 1[m] = %d\n", 1[m]);21 printf(" *(p+1) = %d\n", *(p + 1));22 printf(" p[1] = %d\n", p[1]);2324return0;25 }输出结果为:(2)数组名注意事项1)数组名跟数组长度⽆关;2)数组名可以看作⼀个常量指针;所以表达式中数组名只能作为右值使⽤;3)在以下情况数组名不能看作常量指针:- 数组名作为sizeof操作符的参数- 数组名作为&运算符的参数(3)指针和⼆维数组⼀维数组的指针类型是 Type*,⼆维数组的类型的指针类型是Type*[n](4)数组指针和指针数组①数组指针1)数组指针是⼀个指针,⽤于指向⼀个对应类型的数组;2)数组指针的定义⽅式如下所⽰:int (*p)[3] = &m;②指针数组1)指针数组是⼀个数组,该数组⾥每⼀个元素为⼀个指针;2)指针数组的定义⽅式如下所⽰:int* p[5];3.指针和函数(1)函数指针函数的本质是⼀段内存中的代码,函数的类型有返回类型和参数列表,函数名就是函数代码的起始地址(函数⼊⼝地址),通过函数名调⽤函数,本质为指定具体地址的跳转执⾏,因此,可定义指针,保存函数⼊⼝地址,如下所⽰:int funcname(int a, int b);int(*p)(int a, int b) = funcname;上式中,函数指针p只能指向类型为int(int,int)的函数(2)函数指针参数对于函数int funcname(int a, int b);普通函数调⽤ int funcname(int, int),只能调⽤函数int func(int, int)函数指针调⽤ intname(*func)(int,int),可以调⽤任意int(int,int)类型的函数,从⽽利⽤相同代码实现不同功能,实例测试如下,假设有两个相同类型的函数func1和func2:1int func1(int a, int b, int c)2 {3return a + b + c;4 }56int func2(int a, int b, int c)7 {8return a - b - c;9 }普通函数调⽤和函数指针调⽤⽅式及结果如下所⽰1 printf("普通函数调⽤\n");2 printf("func1 = %d\n", func1(100, 10, 1));3 printf("func2 = %d\n", func2(100, 10, 1));4 printf("\n");56 printf("函数指针调⽤\n");7int(*p)(int, int, int) = NULL;8 p = func1;9 printf("p = %d\n", p(100, 10, 1));10 p = func2;11 printf("p = %d\n", p(100, 10, 1));12 printf("\n");需要注意的是,数组作为函数参数的时候,会变为函数指针参数,即:int funcname( int m[] )<——>int funcname ( int* m );调⽤函数时,传递的是数组名,即funcname(m);(3)回调函数利⽤函数指针,可以实现⼀种特殊的调⽤机制——回调函数。

指针的详细讲解

指针的详细讲解

指针的详细讲解
指针是C语言中重要的概念,也是很多初学者比较困惑的一部分。

在C语言中,指针是一个特殊的数据类型,它直接或者间接地指向了另一个变量或者数据的地址。

指针的基本定义:指针是一个变量,其值是扮演着另一个变量名也就是地址的变量的地址。

指针与变量之间的区别在于,变量存储的是实际的值,而指针存储的是值的内存地址。

指针的类型:在C语言中,指针有不同的类型,这些类型标识了指针指向的变量的数据类型。

例如,int*是一个整数指针,而char*是一个字符指针。

指针的运算:指针可以进行加、减、前后移动等操作。

例如,指针加上一个整数就会指向另一个地址,指针减去一个整数就会回到前一个地址。

指针的使用:指针的主要作用是通过引用来访问变量或者数据。

通过指针,我们可以传递变量的地址而不是变量本身,这样可以减少内存的使用量并提高程序的效率。

指针的注意事项:在使用指针时,需要特别注意指针的安全性。

不正确的使用指针可能会导致内存泄漏、程序崩溃、数据丢失等问题。

总的来说,指针是C语言中一个非常重要的概念,理解它的基本概念和使用方法,对于C语言的学习和开发都有非常重要的意义。

C语言指针的概念

C语言指针的概念

C语言指针的概念C语言指针的概念引导语:在信息工程中,指针是一个用来指示一个内存地址的计算机语言的变量或中央处理器(CPU)中的寄存器(Register)。

以下是店铺向大家介绍一下C语言指针,欢迎阅读!1.1 指针与指针变量的概念,指针与地址运算符1.在C语言中,指针是指一个变量的地址,通过变量的地址″指向″的位置找到变量的值,这种″指向″变量地址可形象地看作″指针″。

用来存放指针的变量称为指针变量,它是一种特殊的变量,它存放的是地址值。

2.定义指针变量的一般形式为:类型名 *指针变量1,*指针变量2,…;″类型名″称为″基类型″它规定了后面的指针变量中存放的数据类型,″*″号表明后面的″指针变量1″,″指针变量2″等是指针变量,″*″号在定义时不能省略,否则就会变成一般变量的定义了。

″指针变量1″,″指针变量2″等称为指针变量名。

3.一个指针变量只能指向同一类型的变量。

4.与指针和指针变量有关的两个运算符:(1)*:指针运算符(或称″间接访问″运算符)(2)&:取地址运算符通过*号可以引用一个存储单元,如有如下定义:int i=123,*p,k;则 p=&I;或k=*p;或k=*&I;都将变量i中的值赋给k。

*p=10;或*&i=10;都能把整数10赋给变量i。

这里,等号左边的表达式*p和*&i都代表变量i的存储单元。

1.2 变量、数组、字符串、函数、结构体的指针以及指向它们的指针变量1.变量的指针和指向变量的指针变量。

2.数组的指针和指向数组的指针变量。

所谓数组的指针是指数组的起始地址,数组元素的指针是数组元素的地址。

C语言规定数组名代表数组的首地址,也就是第一个元素的地址。

3.字符串的指针和指向字符串的指针变量。

我们可以通过定义说明一个指针指向一个字符串。

C语言将字符串隐含处理成一维字符数组,但数组的每个元素没有具体的名字,这一点跟字符数组不一样。

要引用字符串中的某个字符,只能通过指针来引用:*(s+0),*(s+1),…,*(s+n)。

C语言之指针

C语言之指针

指针一、指针的概念指针即地址,一个变量的指针就是指该变量的地址。

注意:指针变量中只能存放地址。

二、指针变量的定义和引用1、指针变量的定义int *p; 此语句定义了一个指针变量p,p中可存放一个整型变量的地址。

注意:①*是指针变量的特征②只是分配了一个存储单元,并没有指真正指向,要想使一个指针变量指向一个整型变量必须赋值。

例如::int *p,I=3;p=&I;如果p=3就是错误的。

2、指针变量的引用(两个有关指针的运算符)①& 取地址运算符号②* 指针运算符*p表示p所指向的变量值。

int *p,a;p=&a; /*指向变量a的值赋给p*/scanf(“%d”,p);/*从键盘输入一个值赋值给p所指向的变量a*/*p=5; /*把5赋值给变量p所指向的a*/三、指针作为函数参数函数的参数不仅可以是整型、实型、字符型等数据,还可以是指针类型,它的作用是将一个变量的地址传送到另一个函数中四、指针与数组1、一维数组的指针表示方法(1)数组中各元素的地址。

int a[10]={1,2,3,4,5,6,7,8,9,10};①&a[0] &a[1] &a[2] 、、、&a[i]、、、&a[9]②a a+1 a+2 、、、a+i、、、、、a+9(2)数组元素值①a[0] a[1] a[2] 、、、、a[i]、、、、a[9]②*(a+0) *(a+1) *(a+2)、、*(a+i) *(a+9)2、二维数组的指针表示方法例:int a[3][4]={1,2,3,4,5,6,7,8,9,10,11,12};1、每行的起始地址①&a[0][0] &a[1][0] &a[2][0]②a[0] a[1] a[2]③a+0 a+1 a+2④*a *(a+1) *(a+2)⑤&a[0] &a[1] &a[2]2、各元素的地址①&a[0][0] &a[0][1] &a[0][2]②a[0]+1 a[0]+2 a[1]+2③*a+1 *(a+1)+1 *(a+2)+23、各元素的值①*(&a[0][0]) *(&a[0][1]) *(&a[0][2])②*(a[0]+1) *(a[0]+2) *(a[1]+2)③*(*a+1) *(*(a+1)+1) *(*(a+2)+2)四、指针与数组;printf(“%d”,*p);注意:int (*p)[5]表示p是指针变量,它指向一个包含5个元素的一维数组int *p[5] 是指针数组。

c语言中的指针是什么

c语言中的指针是什么

c语言中的指针是什么很多学习C语言的新手来说,指针无疑是一个难点。

但是,我觉得指针也是C语言特别重要的一个特性。

那么下面一起来看看店铺为大家精心推荐的c语言中的指针是什么,希望能够对您有所帮助。

为什么说指针是 C 语言的精髓?“指”是什么意思?其实完全可以理解为指示的意思。

比如,有一个物体,我们称之为A。

正是这个物体,有了这么个称谓,我们才能够进行脱离这个物体的实体而进行一系列的交流。

将一个物体的指示,是对这个物体的抽象。

有了这种抽象能力,才有所谓的智慧和文明。

所以这就是“指示”这种抽象方法的威力。

退化到C语言的指针,指针是一段数据/指令(在冯诺易曼体系中,二者是相通,在同一空间中的)的指示。

这是指示,也就是这段数据/指令的起始位置。

但是数据/代码是需要一个解释的方法的。

比如0x0001,可以作为一个整数,也可以作为作为一串指令,也可以作为一串字符,总之怎样解释都可以。

而C语言,在编译阶段,确定了这段数据/指令的“解释方法”。

例如,整型指针,表示的就是可以从这个指针p指向的位置开始解释,解释为一个整数。

一个函数指针,表示的就是可以从这个指针p指向的位置开始解释,解释为一段指令,对应的输入和输出以及返回值按照函数指针的类型,符合相应的要求。

综上,C语言的精髓是指针,但指针不仅仅是C语言的精髓,它是抽象的精髓。

各个语言中都有类似的东西,例如函数,例如引用。

(引用和指针的区别,我的理解,不可以进行+/-偏移操作的指针,就是引用。

随意偏移,很容易使得目标位置不符合其相应的意义,从而造成解释失败,进而崩溃。

而增加了偏移功能的指针,好处是方便表述一堆具有相同类型的数据/指令,数组之类的就是这样的实例。

) 同样的void类型的指针,也是C语言的特色。

void型的指针,就是去掉了指定类型的指针,从而使得可以以任意解释方式,解释指针,这就带来了如上的潜在问题。

但是也可以说,这个C语言的特有威力(我一般都把C语言的威力理解为这个)。

深入解析C语言中函数指针的定义与使用

深入解析C语言中函数指针的定义与使用

深⼊解析C语⾔中函数指针的定义与使⽤1.函数指针的定义函数是由执⾏语句组成的指令序列或者代码,这些代码的有序集合根据其⼤⼩被分配到⼀定的内存空间中,这⼀⽚内存空间的起始地址就成为函数的地址,不同的函数有不同的函数地址,编译器通过函数名来索引函数的⼊⼝地址,为了⽅便操作类型属性相同的函数,c/c++引⼊了函数指针,函数指针就是指向代码⼊⼝地址的指针,是指向函数的指针变量。

因⽽“函数指针”本⾝⾸先应该是指针变量,只不过该指针变量指向函数。

这正如⽤指针变量可指向整形变量、字符型、数组⼀样,这⾥是指向函数。

C在编译时,每⼀个函数都有⼀个⼊⼝地址,该⼊⼝地址就是函数指针所指向的地址。

有了指向函数的指针变量后,可⽤该指针变量调⽤函数,就如同⽤指针变量可引⽤其他类型变量⼀样,在这些概念上是⼀致的。

函数指针有两个⽤途:调⽤函数和做函数的参数。

函数指针的声明⽅法为:数据类型标志符 (指针变量名) (形参列表);“函数类型”说明函数的返回类型,由于“()”的优先级⾼于“*”,所以指针变量名外的括号必不可少,后⾯的“形参列表”表⽰指针变量指向的函数所带的参数列表。

例如: int function(int x,int y); /* 声明⼀个函数 */ int (*f) (int x,int y); /* 声明⼀个函数指针 */ f=function; /* 将function函数的⾸地址赋给指针f */ 赋值时函数function不带括号,也不带参数,由于function代表函数的⾸地址,因此经过赋值以后,指针f就指向函数function(int x,int y);的代码的⾸地址。

2.函数指针使⽤的例⼦ 知道了如何定义⼀个函数指针,但如何来使⽤它呢?先看如下例⼦:#include <stdio.h>#include <string.h>char * fun(char * p1,char * p2){ int i = 0; i = strcmp(p1,p2); if (0 == i) { return p1; } else { return p2; }}int main(){ char * (*pf)(char * p1,char * p2); pf = &fun; (*pf) ("aa","bb"); return 0;} 我们使⽤指针的时候,需要通过钥匙(“*”)来取其指向的内存⾥⾯的值,函数指针使⽤也如此。

指针的定义方法,指针和变量的关系

指针的定义方法,指针和变量的关系

指针的定义方法,指针和变量的关系
指针是 C 语言中的一种特殊数据类型,它保存的是一个变量的内存地址,也就是说指针是可以指向其他变量的。

指针的定义方法是在变量名前加一个星号,例如 `int *p` 表示定义了一个指向整型变量的指针变量 p。

指针和变量之间的关系可以理解为指针是指向变量的一个引用,它可以通过指针来操作变量的值。

当我们声明一个指针变量时,它会被分配一个内存地址,这个地址指向的是一个变量的位置。

通过修改指针的值,我们可以改变指针所指向的变量的值。

相反,通过修改变量的值,我们可以影响指针所指向的内存位置。

指针在 C 语言中应用广泛,特别是在动态内存分配、数据结构和函数参数传递方面。

通过指针,我们可以更方便地管理内存、操作数据结构或传递变量的引用而不用拷贝数据。

但需要注意的是,指针也容易引起一些安全问题,例如指针的空指针、野指针、越界指针等等,在使用指针时需要仔细注意。

相关主题
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

如何透彻理解C语言中指针的概念强大的指针功能是C语言区别于众多高级语言的一个重要特征。

C语言指针的功能强大,使用灵活多变,可以有效地表示复杂的数据结构、动态分配内存、高效地使用数组和字符串、使得调用函数时得到多个返回值。

而它的应用远不限于此。

初学者对于指针的概念总是感到无所适从,有时觉得“自己懂了,为什么编译器就是不懂呢”,常有茫然和无助的感觉。

学好指针的关键在于深入了解内存地址的空间可以理解为一个一维线性空间,内存的编址和寻址方法,以及指针在使用上的一些规定。

事实上,指针就是方便我们对内存地址直接进行操作的,是为程序员服务的,我们只要抓住指针想要帮助我们解决什么问题这个核心,就可以轻松地理解它的工作原理。

什么是指针,指针有什么作用指针就是指向一个特定内存地址的一个变量。

简化了的内存空间模型是按照从0到某一个数(比如1048575=1M-1)的一维线性空间,其中的每一个数对应一个存储单元,即1个字节。

指针有两个属性:指向性和偏移性。

指向性指的是指针一定要有一个确定的指向,偏移性则是体现指针重要应用的方面,即指针可以按程序员的要求向前或向后偏移。

指针的应用往往与数组联系在一起,为了方便说明问题,不妨从数组开始解释指针的偏移。

数组就是许多的变量,它的一个重要特征就是在内存空间中连续地存放,而且是按下标顺序存放。

比如我们定义一个有100个变量的一维整型数组,它一定从内存的某一个存储单元开始按数组下标顺序存放,连续占用100*4=400字节。

当我们定义一个数组时,系统就会自动为它分配一个指针,这个指针指向数组的首地址。

(在本文剩余部分的论述中,不加区分地使用“指向数组的首地址”与“指向数组的第一个元素”这两种说法,事实上这两种说法也是一致的。

)为了让系统了解每一次指针偏移的单位,也为了方便程序员进行指针偏移(让程序员记住一个整形变量占用4字节,一个字符型变量占用1字节……等等是很麻烦的),不用每次去计算要偏移多少个字节,C语言引入了指针的基类型的概念。

基类型的作用就是让系统了解某个指针每次偏移的字节数。

比如,对于一个字符型指针,它每次偏移(比如ptr=ptr+1)所起到的作用就是让指针偏移1字节;而对于一个整型指针,它每次偏移就应该是4字节。

这样操作数组时就带来了方便。

比如对于一个指向某个整型数组起始存储单元(称为首地址)的指针ptr,ptr=ptr+1就表示将该指针指向这个数组的下一个元素的存储单元,即向后移动4字节,而不仅仅是移动一个存储单元(即移动1字节)。

&()、*()、和[ ]运算符的意义在本文中,将&()、*()和[ ]都看成是运算符。

这样可以方便理解这三个概念。

简单地说,&()将某个标识符(比如变量)转化为其在内存空间中的地址,而*()是产生一个对应于某个地址的标识符,[ ]就更复杂一点,ptr[i]表示将ptr这个指针虚拟地按其基类型进行i个单位的后移,再进行*(ptr)运算。

但这是一个虚拟的后移,即ptr[i]并不改变ptr的指向,只是将其后移i个单位并取*()运算的结果算出来了而已。

要改变指针的指向,我们只能通过类似于ptr=ptr+i这样的语句来实现。

实际中,我们往往不愿意经常改变指针的指向,因为指针的移动虽然是自由的,但移动后往往会“移不回来”,因为我们可能无法清楚地确定指针的偏移量。

后面我们将看到,对于用指针来表示的数组,其元素的引用和赋值是完全可以不用改变指向这个数组的首地址的指针指向的,而一旦要改变这个指针的指向,问题就会变得复杂一些,我们在后面有一个关于程序的命令行参数处理例子专门介绍这个问题。

指针类型和系统自动分配的指针指针可以指向几乎所有我们感兴趣的程序设计要素:函数、数组、结构体、链表节点等等。

其中不同函数间往往并不存在严格的线性关系。

链表节点可以根据算法需要在逻辑上(或物理上)不按线性连续存储。

但数组、结构体的共同特征就是它们在物理上都是线性连续存储的。

只要指针指向了它们的首地址,就可以通过简单的偏移来访问各个它们的元素。

指针的偏移性在这两种数据结构中发挥着至关重要的作用。

这时,我们再回想基类型的定义目的,就会有更深层次的认识了。

对于一个数组或结构体,它的基类型长度应当是其元素的长度(这里的长度即指在内存空间中占用的字节数),而不再限于定义为某种简单数据类型的长度。

在我们定义数组和函数时,系统都会为其自动分配一个指向其首地址的指针。

其中,指针在数组中的应用是最频繁的,也是最基础的。

对于一个数组,其名称就是一个指针变量,亦即假如我们定义“int a[10];”的同时就定义了“int *a=a;”(这只是为了说明问题,这样的语句显然是不合法的)。

数组应用中典型的二级指针设定一个指向指针的指针,即设定一个二级指针。

一般认为,指针不宜超过二级,否则会大大增加逻辑错误出现的可能性。

因此,下面详细解释数组二级指针的实现方法及原理。

在此基础上理解指针的其它相关概念是非常简单的。

刚才一直提及指针的基类型,以及对它的正确理解方法。

请在阅读下面论述的过程中不断地考虑“我们所提到的每个指针的基类型是什么”这个问题。

首先我们先要对二维数组进行重新定义,即将一个M*N的二维数组定义为有M个元素的一维数组,它的每个元素都是一个具有N个元素的一维数组。

这种理解方式对于以前学习过Basic、Pascal等语言的程序员来说比较难以接受,因为它们更容易直观地将其理解为一张二维表。

事实上,二维数组在内存中的线性存储是这样实现的:把每一行看作它的一个元素,然后按照一维数组的按下标顺序排列的原则以每一行为单位进行排列。

而对于每一行,也还是按照一维数组按下标顺序排列的原则进行排列。

也就是说,我们可以按行优先的方式将数组的数字逐个“填入”内存空间。

或者也可以说,多维数组在内存中的排列方式是递归定义的。

既然如此,当我们定义“int a[10][10];”的时候,a是什么样的指针呢?是的,a就是一个二级指针。

它的基类型是有10个元素的一维数组,不再是整型变量了。

它所指向的是一维数组指针(第一行的数组指针)。

当我们执行a=a+1的时候,a将指向二维数组第二行的数组指针,而不是第一行的第二个元素,因为基类型的长度决定了a+1跨越了一整行。

因此,我们要得到数组a的(i,j)位置上的元素的值,应该按照下面的步骤来进行:1、 a+i,这表示将a指针移到第i行的首地址。

2、*(a+i),这表示将第i行的首地址转化为第i行的标识符,前面已经述及,*()运算符的作用就是将地址转化为标识符。

但*(a+i)不是第i 行的第一个元素而是一个指针,这个指针的基类型已经变成了整型变量,不再是有10个元素的一维数组了。

或许你要说,第i行的首地址不就是第i行第一个元素的地址吗?那么*(a+i)不就是第i行第一个元素的值了?首先,我们可以肯定*(a+i)不是第i行第一个元素的值,但第i行的首地址的确就是第i行第一个元素的地址。

前面对*()运算符的说明只是一个表面现象,下面的说法可以辅助你理解*()运算符的真正本质:*()将指针还原为其所指,而不是简单地将地址变成这个地址所存储的值。

*()将地址变成这个地址所存储的值这样的说法只对一级指针是正确的。

对于二级指针,*()只是将二级指针还原为其所指,即还原为一级指针。

物理上“第i行的首地址同时就是第i行第一个元素的地址”这一事实,是容易导致混淆的根本原因。

但只我们要从逻辑的角度出发,就可以较为轻松地理解这个问题。

3、*(a+i)+j,这表示将一级指针向后偏移j个单位,要注意*(a+i)这个指针已经是一个以整型变量为基类型的指针了。

这时*(a+i)+j是一个偏移后的一级指针,它的值是a[i][j]元素的地址,亦即它所指的就是a[i][j]元素。

4、*(*(a+i)+j),将一级指针还原为其所指,即得到了a[i][j]元素的值。

理解了以上的概念,将会对指针有全新的认识,而对于二级以上的指针和其它类型的指针,原理也都是类似的。

对指针的更深入理解只有在编程的实践中得到。

从算法设计的角度来看,使用指针对数组进行遍历等操作可降低时间复杂度,因为指针按照基类型偏移1个单位的效率很高。

一维指针数组中的二级指针透彻地理解下面这段程序对于进一步理解指针的原理是很有裨益的。

下面是一个将系统分配的指针(即数组名指针)进行偏移的例子:main(int argc,char *argv[]){while (argc>1) {++argv;printf(“%s\n”,*argv);--argc;}}粗略地看,不难发现这个程序的作用就是将其命令行参数(不包括第一个程序路径及文件名参数)逐个输出。

但其中却用到了二级指针,究竟是也不是,我们从细节入手分析。

首先,argv是一个指针数组,它的每个元素所指向的是每个命令行参数字符串的首地址。

比如,我们的参数是“abc def”,那么argv[1]和argv[2]所指向的就分别是字符串“abc”和“def”的首地址(注意argv[0]指向的是程序路径及文件名字符串的首地址)。

那么,第四行的++argv是什么意思呢?我们知道,一个数组的名称就是一个指针,在没有被改动的情况下,它指向这个数组的首地址。

++argv 的作用就是将argv这个指针(数组名)按照其基类型宽度向后移动一个单位,如果原来argv所指向的是argv这个数组的首地址,那么执行以后它将指向其第二个元素(即argv[1])。

也就是说,这个程序改动了数组名(本身也就是一个指针)的指向,不断将其后移。

理解到这里,你可能已经初步感到问题并不像看上去那么简单了。

下面的一句“printf(“%s\n”,*argv)”更是有意义了。

你会不会觉得奇怪呢?因为printf(“%s”,ptr)或者puts(ptr)所需要的参数都是指针。

既然argv已经是指针,又为什么要在前面再加上一个“*”运算符呢?原因如下:argv确实是指针,但它所指的argv这个数组自己的某一个元素(因为我们已经分析过,argv这个指针是从自己的第一个元素argv[0]的地址开始不断地后移的)。

这看起来和一个指向字符串的指针char *ptr=”string content”是类似的。

但我们在输出ptr指针所指的字符串时是使用printf(“%s”,ptr)而不是printf(“%s”,*ptr)来输出的。

那如果我们的这句话是“printf(“%s\n”,argv)”会怎样呢?程序运行后得到的是一堆乱码。

那这堆乱码是什么呢?这堆乱码实际上是argv这个在不断向后移动的指针的所指,即argv数组的元素的地址(如&argv[1],&argv[2]等),也即指向某个命令行参数字符串的首地址的指针的地址。

相关文档
最新文档