c语言指针范文

时间:2023-12-04 13:59:38

c语言指针

c语言指针篇1

【关键词】C语言;指针;数组;字符串;函数

C语言把内存存储单元的地址视为一种数据类型,而地址起到指向某个存储单元的作用,因此常称地址为“指针”,即指针就是地址。指针变量是用于存放指针(即地址)的变量,该变量的值是一个指针,一个要访问对象的地址。在C语言中,引入指针变量的目的主要是用来间接访问数据对象,有效地表示复杂的数据结构。例如:设有指向整型变量的指针变量p,要求指向整型变量a,那么用C语言可描述为:

int a=100;/*定义整型变量a,并赋初值100*/int*p=&a;/*定义指针变量p,并将变量a的地址送给p*/用图表示为:

要存取变量a的值,有两种方法可以完成。一种可通过变量名直接对内存单元进行存取操作,这种方式称为直接访问。另一种方式:先找到存放“a的地址”的变量p,从中取出a的地址(2000),然后到这个地址中对a进行存取a的值,这种访问方式称为间接访问。通过对变量p进行取内容运算*p值就得到a的值100。

有时为了方便,常将指针变量简称为指针。正确而灵活地运用指针不仅能够提高效C程序的效率,而且能有效地表示复杂的数据结构。所以指针的主要用途有:进行指针运算;引用数组元素;使用字符串;作为函数参数,实现地址传递;处理链表等等。

1.指针运算

指针的运算主要指指针的算术运算,其实质就是指向的地址发生变化。指针实际增(减)多少由指针的类型决定。指针加上(或减去)一个整数n,表示将指针由当前位置移动到后面(或前面)的第n个数据处。两个指针相减,表示两指针所指向的地址相减。得到两指针之间数据的个数,结果是一个整数,而不是地址值。如:

int a[5]={2,4,6,8,10};/*定义一个整型数组a并初始化*/

int*p=a,*q=a;/*定义指针p和q,均指向a数组的首地址*/

当p=p+2时,表示将指针p向后移动的二个数据,移向了a数组中第3个数组元素(即6),p-q结果为p与q这两个指针之间数据的个数等于2。利用这个特点,若将p指向数组a的首地址,将p移到a数组的末尾,则用p-q就可以求出数组a的长度,即a中数据的个数。

2.数组与指针

数组在内存中占据一块连续的存储区,数组名代表这个区域的起始地址,即数据名是一个指向该数组首地址的常量指针。当指针指向一维数组首地址后,C语言可有4种直接访问该数组的第i个元素的方法:“数组名[i]”,“指针名[i]”,“*(指针名+i)”,“*(数组名+i)”。前两种使用了数组的下标,称为“下标法”。后面两种使用指针运算符,称为“指针法”。

如:int a[10],*p=a;

则:对数组元素a[i](0

a[i]或p[i](下标法);*(a+i)或*(p+i)(指针法)

例如:以下程序有两个功能完成的函数(计算数组中各元素值的总和)。

int sum1(int a[],int n)/*函数1*/

{int sum=0,*p,*q=a+n;

for(p=a;p

sum+=*p;

return(sum);

}

int sum2(int a[],int n)/*函数2*/

{int sum=0,i;

for(i=0;i

sum+=a[i];

return(sum);

}

main()

{int a[5]={2,4,6,8,10};

printf(“%d”,sum1(a,5));

printf(“%d”,sum2(a,5));

}

上述主程序分别调用sum1()和sum2(),调用结果都为30,说明sum1()与sum2()功能完成相同,从表面看来,函数2似乎比函数1简单、直观,但其执行速度sum1比sum2要快,效率要高。

3.字符串与指针

访问一个字符串,除了用字符数组外,还可以定义一个字符指针,用字符指针指向字符串中的字符。如:char*p=“C Program”;这样,可以方便地用字符指针p来处理字符串。

如:打印图案:

*

**

***

****

*****

下面3个程序都能实现”

程序1:

main()

{int i,j;

for(i=1;i

{for(j=1;j

printf(“*”);

printf(“\n”);

}

}

程序2:

Void gra(int n)

{int j;

for(j=1;j

printf(“*”);

printf("\n");

}

main()

{int i;

for(i=1;i

gra(i);

}

程序3:

#include“string.h”

main()

{char a[5]=“*****”,*p;

for(p=a;p

printf(“%s\n”,p);

}

程序1用常用的两重循环结构实现;程序2在main()函数中5次调用gra()函数(gra()函数的功能是打印输出每一行中的“*”符号);而程序3中用一个字符指针p指向字符串,通过一个单循环,每一次输出一行中的“*”符号。由此可见,程序3最方便。所以,如果能灵活运用指针,可以使程序更简洁、更紧凑、更高效。

4.函数与指针

函数调用时,数据的传递可采用数值传递、地址传递、返回值等方式。

数值传递一般指参数为普通变量,这种方式无法通过调用函数来改变实参变量的值,有时也称这种数据传递是“单向的”。如:

Void f1(int p)

{p=p+3;}

.

.

.

int x=2;

f1(x);/*调用函数f1后,实参x的值仍然为2*/。

如果用指针作为函数参数,采用地址传递方式,却能改变实参的值。如:

Void f2(int*p)

{*p=*p+3;

}

.

.

.

int*q,x=2;

q=&x

f2(q);/*调用函数f2后,实参x的值改变为5*/。

返回值方式只能从被调函数中将一个值返回主调函数,如果上例中用指针作为函数实参和形参,采用地址传递方式则能改变实参的值。因为当调用者与被调用者之间是以指针变量作为参数进行传递时,调用者是把实参指针变量的值赋给被调用者的形参指针变量,于是实参指针和形参指针指向同一个地址,实现的地址的传递,当对形参所指变量的处理,也就是对实参做了相同的处理。如:地址传递方式可以得到多于一个的值”

Void f3(int*p)

{*p=1;

*(p+1)=2;

*(p+2)=3;

}

.

.

.

int a[3];

f3(a);/*调用函数f3后,实现了对a[0]、a[1]、a[2]的赋值,s[0]=1,s[1]=2,s[2]=3*/

此外,通过指向一个函数的指针,还可以调用相应的函数。

如:doublex,(*p)(double);/*A行,定义一个指向返回浮点型值的函数的指针p*/。

p=sin;/*B行,将正弦函数名sin赋给p*/。

x=(*p)(3.14/6);/*C行,通过指针p调用正弦函数sin*/。

函数名代表该函数的入口地址,所以B行赋值语句“p=sin;”的作用是将sin的入口地址赋给指针变量p。这时,p就是指向函数sin的函数指针,也就是p和sin都指向函数的开头。根据本文所列的参考文献[1][2],通过函数指针调用函数的格式为:(*指针名)(实参表);所以,上面的C行写成:x=(*p)(3.14/6);直接调用库函数sin的格式为:函数名(实参表),如:x=sin(3.14/6);那么,既然把sin赋给了函数指针变量p,则变量p就和sin具有相同的内容。能不能用格式:指针名(实参表)呢?经试验,结果运行完全正确。所以,C行可以改成x=p(3.14/6)。函数指针的这种用法更简单,且也更容易理解[3]。

5.结语

指针运用千变万化。对熟练的程序人员来说,可以利用它编写出颇有特色的、质量优良的程序,实现许多用其他高级语言难以实现的功能,但指针使用实在太灵活,也十分容易出错。所以,要学好指针,一定要在实践中不断摸索,从而能够更好地驾驭指针。

参考文献

[1]迟成文.高级语言程序设计[M].北京:经济科学出版社,2000.

[2]谭浩强.C程序设计[M].北京:清华大学出版社,1999,2.

[3]康牧,杨泽民.如何用简单的方法使用C语言[J].雁北师范学院学报,2002,18(5):30-240.

[4]HerbertS.C The Complete Reference[M].New York McGraw2Hill 1993.

c语言指针篇2

1.1指针算法定义在计算机内存中,每一个存储单元(通常为1字节)都有一个固定的编号,就像酒店中的房间号码一样,这个编号就称为地址,相当于房间号。在地址所标识的内存单元中存放数据,这就相当于酒店中各个房间里居住的旅客一样。

1.2引用指针算法变量&和*是C语言有关指针算法的两个重要运算符,分别是取地址运算符和指针算法运算符。例如:&x为变量x的地址,*p为指针算法变量p所指向的存储单元。应该注意的是在定义时*只起说明作用,不是运算符。比如下面的语句中:floatx=1.5float*P=&xfloat*P=x很多同学在这里有些迷惑,到底是第2条语句正确还是第3条语句正确呢?根据指针算法的定义很显然第2条语句是正确的。迷惑的原因就在把*当成了运算符。其实,这里的float*共同来修饰P,定义一个指向浮点型的指针算法变量,同时要将一个指针算法&x赋值给P。为了方便对存储单元进行控制,我们可以设置某些变量专门存放指针算法,这样的变量称为指针算法变量。在课堂教学中,应注意使学生明白内存单元地址与内存单元内容这两个概念的区别,很多初学者在这个概念问题上常常弄混淆。

1.3指针算法与数组

1.3.1指针算法与数组区别。在C语言中数组与指针算法的关系非常密切,但它们还是有着本质上的区别。指针算法可以随时指向任意类型的内存单元,它的特征是可变。所以我们常用指针算法来操作动态内存。当数组作为函数的参数进行传递时,该数组自动退化为同类型的指针算法。例如:charx[]=chinachar*p=china上述两个变量的内存布局情况是:数组x需要在内存中占用6个字节的空间。这段内存区通过数组名x来标志。指针算法P则需要4个字节的空间来存放地址,这4个字节用P来标志。其中存放的地址几乎可以指向任何地方,也可以哪里都不指。目前这个P指向某地连续的6个字节即字符串china。在教学过程中应该注意使学生能够正确认识数组与指针算法的区别,并正确运用它们。

c语言指针篇3

关键词 C语言;指针;程序设计

中图分类号TP39 文献标识码A 文章编号 1674-6708(2011)56-0173-02

1 C语言中的指针简介

指针就是表示地址的一种变量,所以指针的范围严格来说只能是自然数的,并且不能在两个指针间进行加、乘、除这样的运算。由于在C语言中每个数据类型都必有存储空间,所以指针可以应用于几乎所有的数据类型中。所以,从这个角度出发可以将指针分为:指向变量的指针、数组指针、字符指针、指向指针的指针、函数指针、结构变量的指针以及文件指针等等。

其中,指向变量的指针就是存储变量的地址的。如 int * s这就是一个指向整型的指针,可以用于指向一个整型变量。如int a; 当p=&a时,就是将p存储整型变量a的地址。这是指针最简单的一种类型。所谓数组指针,就是指数组的名称实际上是指向整个数组空间的首指针。如 int a[10];其中a本质上是一个指针,指向该数组的第一个位置,a[2]表示距离a指向空间向后2个位置所在空间中的存放的值。所以,a[2]=*(a+2)。字符指针本质上是数组指针的一种特殊情况,就是存放字符串的数组所对应的数组名。指向指针的指针这是一类很特殊的指针,用于存放指针的一类指针,在本质上与指向变量的指针十分相似。例如 char *ss[N]={“java”,”sss”,’’rrr”}。指向函数的指针就是指向函数入口地址的指针。结构变量的指针这类指针和指向变量的指针很类似,主要的区别在于结构变量可能有多个类型不同的变量,所以一般空间较大。文件指针就是对文件进行操作的指针。从上述的分类可以看出无论什么类型的指针其功能都是一样的就是用于指向对象的地址空间罢了。

上面简要的介绍了指针的定义和分类,现在简要的论述一下指针涉及到的运算操作。首先由于指针是存放的变量地址的,所以第一个操作就是对指针进行地址赋值。如int a,*p;

P=&a,这就是对指针p进行进行赋变量a的地址,p指向变量a。当然也可以通过指针获取指针指向地址空间所存储的值。如int b=2,*p;p=&a,这是*p就表示p指向空间所存储的值,在本例中就是a的值2。为了能在数组指针中通过指针能访问到整个数组的值,所以。可以对指针进行加减整数值,表示地址的前移或后移。如int a[10],*p,*s; p=a;s=p+2;其中s 的值表示数组中首地址向前移动2的位置,表示 a[2]对应的地址。 为了表示两个地址间存在的距离,可以通过指针间的减法实现。当然指针涉及到的还有其他运算,现不详述了。

2 C语言中的指针算术运算

指针可以加上或减去一个整数,这和c语言中的算术表达式意义是不同的。例二:

(1)int a[20]; (2)int *ptr=a; (3)……… (4)ptr++;

在上例中,指针ptr的类型是int*,它指向的类型是int,他被初始化为指向数组a的起始地址,接下来的第4句中,指针ptr被加了1,编译器编译程序时把指针ptr的值加上了sizeof(int)。

由于int型在32位机中的长度是4个字节,故原来ptr指向数组第0号单元开始的四个字节,此时指向数组从第4号单元开始的4个字节。

3 运算符&和*

&是取地址运算符,*是指针运算符或称为间接访问运算符。&a的运算结果是一个地址,即变量a的地址。*p为指针变量p所指向的存储单元的内容,即p所指向的变量和值。下面举例说明。例三:

int a=12;

int b;

int * p;

int * * ptr;

p=&a; /*把变量a的地址赋给指针变量p。 */

*p=24; /*把24赋给指针变量p所指向的存储单元的内容 */

ptr=&p; /*把指针变量p的地址赋给指针变量ptr。*/

*ptr=&b; /*把变量p的地址赋给指针变量ptr。 */

* *ptr=34; /* *ptr的结果是ptr所指向的存储单元的内容,即变量b的地址,再做一次*运算,结果就是一个int类型的变量。*/

4 C语言中的指针应用

在C语言中指针的十分应用广泛,除具有一般的功能外,具体特殊功能的应用总结起来有三个方面:一是用于在函数中可以返回多个值;还有就是可以实现动态调用函数;最后就是实现数组的动态定义。其中,由于由函数的特点,一个函数只能有一个返回值,但在有些场合需要返回多个值,就可以定义指针参量来实现,其定义的基本框架如下:

Sss( int a,int *p )

{int s;

…….

………

Return s;

}

在这中情况下,函数不仅可以得到返回值(通过Return s来实现的),还可以通过指针p来返回相应的值。所谓指针能实现动态调用函数,这里用到的指针就是上文中提到的函数指针。函数指针就是指向函数入口地址的指针,我们还知道其实函数名就是一个函数指针。我们就是通过函数名实现动态调用函数的。在主调函数的参数中采用函数名充当实参就能实现函数的动态调用。该方法以简短的代码实现了复杂的功能。最后讲到指针能实现数组的动态定义。从C语言的学习中,我们知道在定义数组时一定要指定数组的大小,否则,不能完整数组的定义。那么如何实现数组的动态定义。数组从本质上来讲就是连续的空间集合罢了。那么,我们可以通过申请一个空间并赋值给一个指针变量,以此指针变量为首空间,就能获取连续的空间,这与数组相同。当然数组还有许多应用,只有认真分析就能得到更多更好的应用实例。

5 结论

指针是C语言中的一个重要概念,也是C语言的一个重要特色。掌握指针的应用,可以使程序简洁、紧凑、高效。每个学习和使用C语言的人,都应当多思考、多上机,在实践中深入的学习和掌握指针。

参考文献

[1]谭浩强.C语言设计[M].北京.清华大学出版社,2005,7.

[2]张丽霞.C语言指针详解[J].赤峰学院学报:自然科学版,2005,21(5):37-38.

c语言指针篇4

关键词:C语言指针;创新思维;探究发现;学以致用

中图分类号:G712 文献标识码:A 文章编号:1671-0568(2013)32-0075-02

指针是一个重要的数据类型,指针的应用可以使代码高效、简洁,但也最容易出错。指针在函数传值、内存使用、数组遍历等使用上的灵活性及其类型的多样性,使得指针教学成为C语言教学的重点,也是难点,是教师与学生花精力和时间最多,而效果相对较差的知识点。在C语言教学中,指针的讲授往往处于非常尴尬的地位,教师与学生都感到心有余而力不足。

一、教学现状

指针的类型很多,这是学生正确使用指针的一大障碍。指针变量的值是一个整数(内存字节编号),但与int不同,它代表内存的一个地址,需符合系统的地址编码规则。使用时可以指向不同的数据类型,学生很容易犯错。

C语言规定,指针变量只能进行加减法运算:指针变量-指针变量,参与运算的指针变量必须是同类型的指针变量并指向同一块有效的内存区域才有意义,其结果是一个整数;指针变量的值±整数其结果为指向同一块有效的内存区域,且该内存区域保存的数据类型与指针变量类型相同才有意义,对比较运算也有相同的限制。这也是学生很难理解的知识点,使用时容易出错。

讲授指针赋值操作时,只是告诉学生有两种方式:一种是把某个同类型变量的地址或同类型指针变量的值赋给一个指针变量;另一种是把申请内存库函数的返回值赋给一个指针变量。学生难以理解直接赋一个地址给指针变量为什么经常出错。

二、基于创新思维的教学

1.创新思维内涵

创新思维就是把已有的思维材料进行整理抽象,以适应新的环境,进而求解新的问题。在教学中,采用何种方法能启发学生获得知识呢?美国教育家布鲁纳主张教学采用“探究发现”法,引导学生像科学家那样探求知识,而不是被动接受教师的灌输。不论是在校学生的发现,还是科学家致力于日趋尖端的研究领域的发现,按实质来说,都是把现象重新组织和转换,使人能超越现象再进行组合,从而获得新的领悟。

对教学而言的创新思维,一般是指对引导学生利用已有的知识,发现新问题、引入新方法、解决新问题,使学生了解创新的过程与方法,理解理论源于实际的本质,进而培养学生的创新思维和科学素养。

2.基于创新思维的指针教学

C语言规定,指针变量只能保存地址,其实在学习指针之前,学生已经使用过地址。如代码int x;scanf(“%d”,&x);&x就是变量x的地址,代码的含义就是声明一个int型变量x,并把x的地址传给scanf()函数。学习指针之前,只告诉学生记住变量前的&;学习指针之后,教师就应根据内存模型,告诉学生在计算机中每个内存空间(字节)对应的地址是唯一的,scanf函数功能就是把从键盘上输入的数据保存在内存中,供主调函数使用。所以,主调函数只要把变量地址(内存地址)传递给scanf函数即可。这个地址是对scanf函数,主调函数都是可见,因而都可以操作其中的数据,这样就实现了scanf函数的功能。

为了引导学生利用创新思维,学习新知识指针。可以帮助学生回顾,当计算机执行类似int x;这样的声明语句时,系统的行为,来建立新旧知识的联系。①系统给x分配了与int类型相符的连续空间(vc是4字节);②系统记录了这个空间第一个字节的编号,即x的地址;③系统标识了这个空间中保存的数据是int类型的数据。

在程序开发中,经常需要把多个具有相同属性的数据保存在连续区域,而数据的个数需要到运行时才能确定。只要能记住这块内存开始的位置(即内存地址,也就是第一个字节的编号),通过简单的加减整数操作访问到全部的数据。

首先,教师需要引导学生思考,C语言程序要实现这种场景就必须引入新的数据类型:这个数据类型的变量可以保存数据空间地址,可以与一个整数相加减,还需要标识保存在数据空间中的数据的数据类型。指出这种新数据类型就是C语言中的指针类型,它具有两种属性(地址及保存在该内存空间数据的数据类型),给出新的数据类型——指针变量的声明格式。例如,int * x;其中*标识x是一个指针变量,int标识这个x中只能保存int类型数据空间的地址。

其次,教师引导学生分析这种新的数据类型,如int *x;根据学过的变量声明格式可知,x是一个int *类型的变量(int类型的指针变量),*x是一个int类型的变量。通过例子,利用数据的有效性,使学生明白x中的值必须是系统分配给程序的有效内存的地址才有意义,从而理解指针运算的本质。此时,学生经历一个完整的发明过程,从应用中发现现有知识不能解决或不完美,进而引入一个能解决问题的新数据类型来圆满解决问题。这就是创新思维。学生在学习新知识的同时,建立了新旧知识的联系及使用场景。

最后,教师指导学生进行总结,声明指针变量时(int *x;),系统的行为:①系统给x分配了与地址值相符的连续空间(vc是4字节);②系统记录了这个空间第一个字节的编号,即x本身的地址;③系统标识了x中只能指向保存int类型数据的内存空间;④x中的值必须是系统分配给程序的有效内存空间的地址才有意义。

引导学生总结指针变量的运算规律,计算机的内存有很多,但只有系统分配给程序的内存才能被使用。在程序中对指针变量进行操作,其本质是为了对指针变量所指向的内存地址中的数据进行操作。要使指针变量指向有效的内存空间,那么指针变量与指针变量之间只是减法运算,而且参与运算的指针变量是指向同一块连续的内存空间才有意义。指针变量与整数运算的结果一定是与指针变量所指向地址属于同一块连续的有效内存空间才有意义。

对于比较运算来说,其本质是由地址的特点决定的:地址值是内存空间编号,只是序号而已。因此,指针变量的比较运算只是为了确定内存空间的位置关系,而内存空间的位置关系只有指向同一块连续的有效内存空间才有意义。加法、乘法、除法等运算,都不能保证运算结果,是一个系统分配给程序的有效内存地址,因而C语言规定指针变量进行这些运算是不合法的。

基于创新思维的教学,引导学生按照知识获取的规律学习,理论源于实践,当原有的知识不能解决问题时就需引入新的理论,并利用新知识解决问题,达到学以致用的目标。

参考文献:

[1]李俊萩等.C语言指针教学中的知识点分析与总结[J].计算机教育,2011,(08).

[2]于福生等.C语言课程中指针内容体系设置的改革尝试[J].计算机教育,2013,(04).

[3](美)杰罗姆.S.布鲁纳.布鲁纳教育论著选[M].邵瑞珍,张渭城译.北京:人民教育出版社,1989.

c语言指针篇5

关键词:函数指针,指针函数,地址

 

1.引言

一个程序由两部分组成:代码部分和数据部分。当在程序中定义变量时,编译系统就会为变量分配相应的存储单元,由此就形成了地址的概念。数据在内存中是存放在某一地址上的,代码同样也是存储在内存中的某一地址上,因此指针即可向内存中存储的数据也可以指向程序中的代码,这就是函数指针。而指针函数则是指返回值是一个指针的函数。

2.函数指针

可以用指针变量指向整型变量、字符串、数组,也可以指向一个函数。在C语言中规定,一个函数总是占用一段连续的内存区,而函数名就是该函数所占内存区的首地址。我们可以把函数的这个首地址(或称入口地址)赋给一个指针变量,使该指针变量指向该函数。然后通过指针变量就可以找到并调用这个函数。论文参考网。我们把这种指向函数的指针变量称为“函数指针变量”。

函数指针变量定义的一般形式为:

类型说明符(*函数指针变量名)(形式参数表);

例如: int(*pf)( );

表示pf是一个指向函数入口地址的指针变量,该函数的返回值(函数值)是整型。

下面通过例子来说明用函数指针形式实现对函数调用的方法。在我们没有学习指针变量之前,我们调用函数时是通过函数名来完成的。

2.1用函数名实现函数的调用

源程序代码如下:

#include<stdio.h>

int max(inta,int b)

{if(a>b)return a;

elsereturn b;}

void main()

{ int max(inta,int b);

int a,b,c;

printf('inputtwo numbers:');

scanf('%d,%d',&a,&b);

c=max(a,b);/*用函数名调用*/

printf('max=%d ',c);

}

程序运行结果如下:

2.2用函数指针来实现函数的调用

源程序代码:

int max(inta,int b)

{if(a>b) returna;

else return b;}

void main()

{ int max(inta,int b);

int (*pmax)(int ,int ); /*定义了一个指向整型函数的指针*/

int a,b,c;

pmax=max;/*使函数指针指向该函数的入中地址*/

printf('inputtwo numbers:');

scanf('%d,%d',&a,&b);

c=(*pmax)(a,b);/*通过指针调用max函数*/

printf('max=%d ',c);}

程序运行结果如下:

实例说明:

(1) 本实例中“int (*pmax)( int ,int );”用来定义pmax是一个指向函数的指针,该函数有两个整型参数,函数值为整型。

(2) 赋值语句“pmax=max;”的作用是将函数max的入口

地赋给指针变量pmax(函数名代表该函数的入口地址)。

这时,pmax就是指向函数max的指针变量,此时pmax

和max都指向函数的开头,见右图。调用*pmax就是调

用max。

(3) 请注意:pmax是指向函数的指针变量,它只能指向函数

的入口处而不能指向函数中间的某一条指令处,因此不能

用 *(pmax+1)来表示函数的下一条指令。

(4) 在main函数中有一个赋值语句:

c=(*pmax)(a,b);与实例2.1中c=max(a,b);等价。这就是用指

针形式实现函数的调用。以上用两种方法实现函数的调用,结果是一样的。论文参考网。

2.3使用函数指针

问题:编写程序,根据用户的选择分别调用sin 、cos、 tan函数计算一个角度的三角函数值。角度值从键盘输入。

源程序代码如下:

#include<stdio.h>

#include<math.h>

main()

{double(*p[3])(double)={sin,cos,tan};

intchoice,angle;

printf('Pleaseinput angle=?');

scanf('%d',&angle);

printf('Pleaseinput choice(0-sin,1-cos,2-tan)=?');

scanf('%d',&choice);

printf('%lf ',(*p[choice])(angle*3.14159/180));

}

实例说明:

(1)在本实例中“double (*p[3])(double)={sin,cos,tan};”定义了一个具有3个元素的函数指针数组p,其中3个元素分别指向数学函数sin、cos、tan。

(2)当程序运行时给angle赋值30,给choice赋值0。则:

程序中“priintf('%lf ',(*p[choice])(angle*3.14159/180));”

转换为:

“printf('%lf ',(*p[0])(30*3.14159/180));”(与“printf('%lf ',sin(30*3.14159/180));”等价)。

程序运行结果如下:

3. 指针函数

一个函数可以返回一个整型值、字符值、实型值等,也可以返回指针型的数据,即地址。指针函数则是指返回值是一个指针的函数。在C语言中允许一个函数的返回值是一个指针(即地址),这种返回指针值的函数称为指针函数。论文参考网。

定义指针型函数的一般形式为:

类型说明符 *函数名(形参表)

{

…… /*函数体*/

}

如: int *pf(int x,int y)

{

...... /*函数体*/

}

pf是函数名,调用它以后能得到一个指向整型数据的指针(地址)。x、y是函数pf的形参,为整型。请注意在*pf 两侧没有括号,在pf的两侧分别为*运算符和()运算符。而()优先级高于*,因此pf先与()结合。显然这是一个函数形式。这个函数前面有一个*,表示此函数是指针型函数(函数值是指针)。最前面的int表示返回的指针指向整型变量。对C的这种定义形式,用时要十分小心。

例:有若干个学生的成绩(每个学生有4门课程),要求在用户输入学生序号后,能输出该学生的全部成绩。

源程序代码如下:

#include<stdio.h>

void main()

{floatscore[][4]={{60,70,80,90},{56,89,67,88},{34,78,90,66}};

float*search(float(*pointer)[4],int n);

float *p;

int i,m;

printf('inputthe number of student:');

scanf('%d',&m);

printf('Thescores of No.%d are: ',m);

p=search(score,m);

for(i=0;i<4;i++)

printf('%5.2f ',*(p+i));

printf(' ');

}

float*search(float(*pointer)[4],int n)

{float*pt;

pt=*(pointer+n);

return(pt);

}

程序运行结果如下:

4.结束语

特别注意的是函数指针和指针函数这两者在写法和意义上的区别。如int(*p)()和int *p()是两个完全不同的量。int(*p)()是一个变量说明,说明p 是一个指向函数入口的指针变量,该函数的返回值是整型量,(*p)的两边的括号不能少。int *p() 则不是变量说明而是函数说明,说明p是一个指针型函数,其返回值是一个指向整型量的指针,*p两边没有括号。作为函数说明, 在括号内最好写入形式参数,这样便于与变量说明区别。 对于指针函数定义,int *p()只是函数头部分,一般还应该有函数体部分,这样才能构成一个完整的函数结构。

参考文献:

[1] 陈强.C语言核心开发技术从入门到精通[M].北京:电子工业出版社,2009.

[2] 匡松.C语言程序设计[M] .北京:中国铁道出版社,2008.

[3] 李俊杰.C语言复习指南与题解[M] .北京:清华大学出版社,2003.

[4] 谭浩强.C程序设计[M] .北京:清华大学出版社,2005.

 

c语言指针篇6

关键词:C语言;指针;指针引用

中图分类号:TP393 文献标识码:A 文章编号:1009-3044(2017)04-0077-02

指针是C语言程序设计的重点和难点内容之一,是学好数据结构课程的基础,灵活掌握指针,可以编写出简洁、紧凑、高效的程序。但是在实际教学中往往由于指针的概念抽象,学生理解起来比较困难,在使用过程中由于对指针概念的理解不到位,而经常出错,甚至犯一些不必要的错误。本文针对初学指针的学生容易出错及混淆的地方,结合简单的例子谈谈如何正确使用指针及指针使用过程中常见的错误。

1 指针概念的理解

指针是C语言中一种特殊的数据类型,指的是存储器内存单元的地址,每个内存单元都对应着一个特定的地址编号,一个内存单元可以存放一个字节的数据(二进制代码),计算机是通过内存单元地址访问内存单元中所存储的数据。由于计算机所处理的数据的类型各不相同,不同类型的数据在存放到计算机内存时都会占用不同个数且连续的存储单元,计算机读取该数据时将根据该数据的第一个存储单元地址(首地址)和该数据的类型(决定访问几个内存单元数)访问这个数据,以VC++6.0编译器为例,char型数据占用1个存储单元,int型数据占用4个连续的存储单元,下面以例1为例进行说明。

例1:int a,b;a=80;b=90;

假设编译系统为变量a分配的内存单元的起始地址(首地址)为2050,变量a将占用2050~2053这四个连续的内存地址所对应的存储单元;同样假设为变量b分配的内存单元起始地址(首地址)为2054,变量b将占用2054~2057这四个连续内存单元。对于a=80;语句来说,系统先找到数据a的起始地址2050,然后,根据a变量的数据类型将数据80写入2050~2053这四个内存单元中, 变量b 的值90写入2054~2057这四个连续内存单元。这是由系统按照变量名称进行的数据访问(称为数据直接访问)(见图1)。当然,如果把变量a或b的起始地址放到指针变量p或q中,就可以间接通过量p或q来访问变量a或b了(称为数据间接访问)(见图2),这就是能够利用指针变量访问数据的原因。下面通过指针变量的定义来说明如何正确使用指针。

2 指针变量的定义及正确使用

指针变量定义的语法格式:*[=];通过定义指针变量就可以来间接访问它所指向的对象。通过例2进行说明。

例2:int a;int *p=&a;*p=30;

语句int a;表示定义了一个普通的整形变量a,语句int *p=&a;表示定义了一个整型指针变量p,且其内容为整型变量a的地址值,假设a的地址为2050。通过这两条语句的定义,整型指针变量p就指向了整形变量a,那么就可以通过p间接访问其所指向的对象a了。语句*p=30;就是利用指针变量p访问数据a的方法,*称为指针的间接引用运算符,*p表示p所指向的对象即a,操作*p就像操作a一样(操作结果见图3),在给a赋值的时候可以使用a=30;也可以使用*p=30来操作。

[\&\&图3 利用指针变量p访问变量a\&图4 指针未赋值错误\&]

2.1 指针变量在使用之前必须进行赋值

定义指针变量的目的是使用指针变量,即利用指针变量访问它所指向的对象,所以指针变量在使用之前必须有一个确定的值,即把一个同类型的地址赋值给指针变量。因为没有赋值的指针变量其内容是一个随机的地址值,该地址所对应的单元可读性未知,把一个数据写入该地址中,容易造成无法估计的错误。

例3:int *p;*p=80;在本例中,p在使用之前没有进行赋值,p没有指向任何一个变量,其值为一个随机的地址,假设编译系统为p分配的值为1000,则执行*p=80;后,将80写入1000~1003这四个内存单元中,有可能会造成对这四个内存单元原数据的破坏,所以发生运行错误(见图4)。可以进行如下修改:

int a,*p;p=&a;*p=80;

2.2 指针变量与指针所指对象变量

指针变量与指针所指对象变量是两个不同的变量,它们的类型是不同的。如:int a,*p;p=&a;p与*p是两个不同数据,p是指针变量,而*p是p所指的对象即a。在指针定义过程中变量p前面的*表示p是一个指针变量,而在引用指针时*表示间接引用运算符。在给指针赋值时,不能把一个普通的整形值直接赋给指针变量。

例4:int a=1000,*p;p=a;该例会提示类型不符错误。因为p的类型为int*型,而a的类型为int型。可以做如下修改int a=1000,*p;p=&a;

2.3 不同类型的指针不能相互赋值

指针是有类型的,给指针赋值,不但必须是一个地址,而且应该是一个与该指针类型相符的变量或常量的地址。

例5:int *p;float a;p=&a;*p=80.5;printf("%f\n",a);本例试图将p指向a,通过*p修改a的值,但是由于指针p与&a类型不符,因此输出a的值并不是想要的结果,本例错在指针类型不符,p是一个整型指针变量,类型为int*,而&a是浮点型指针,类型为float *,故而不能通过一个指向整形的指针变量来操作非整形变量的数据。本例可做如下修改:float a=20.5,*p;p=&a;*p=80.5;printf("%f\n",a);。

2.4 指针变量在操作数组元素时需注意的地方

指针变量的一个重要的使用就是访问数组元素,当一个指针变量指向一个一维数组时,指针变量加上或减去1个整数n,得到的值将是该指针指向前或指向后n个数据元素的地址,而不是普通意义上的加减运算。

例6:int a [5]={1,2,3,4,5},*p=a;*p=10;p=p+1;*p=20;*p++=30;

在本例中指针变量p的初始值为数组a的起始地址,即a[0]元素的地址。然后*p=10;使a[0]得值变为10,执行p=p+1;语句后,指针变量p将指向a[1]元素,故而*p=20;语句将使a[1]元素的值变为20。最后一条语句的执行过程为:由于*和++为相同优先级,并且结合性为从右向左结合,故而等价为执行*(p++)=30;即等价于*p=30;p++;即先修改p指向对象a[1]的值为30,而后将指针p加1,p最后将指向a[2]元素。如果最后一条语句为:*++p=30;则为*(++p)=30;等价于语句p=p+1;*p=30;使指针p先指向a[2]元素,然后修改a[2]元素的值为30。

在利用指针访问数组元素时,也要注意越界题,如例6所示,当有语句*(p + 5 )或*(p - 1 )等书写语句时都会发生数组元素访问越界的运行错误。

2.5 数组名是指针常量,不能当变量使用

数组名也是一个指针,表示的是该数组的起始地址,即第一个数组元素的首地址。但是数组名是一个指针常量,其值在运算过程中是不能修改的,只能作为右值来使用。

例7:利用数组名访问数组元素

int a [5]={10,20,30,40,50};

for (int i = 0;i < 5;i + + )

printf (″%d″, *(a + +)) ;

该例通过指针法要输出数组中的每一个元素,但是由于a是一个常量,值不能在运算时进行修改,因此该例错在*(a + +)上。可以进行如下改正:

printf(″%d″, *(a + i ));

3 结束语

指针是C语言的精华,内容涉及比较多,在此只针对初学指针的学生容易出错的地方做了简单的举例及说明,在实际使用指针过程中,由于指针错误往往比较隐蔽,难以发现,所以必须通过大量地上机调试相关程序,才能弄清指针程序的细节,提高指针的理解能力。

参考文献:

[1] 谭浩强.C程序设计(第四版)[M].北京:清华大学出版社,2010.

[2] 许永达.C语言指针错误的分析及调试[J].计算机系统应用,2013(3):153-156.

[3] 杨智明.C语言指针使用分析[J].保山学院学报,2012,31(2):67-70.

c语言指针篇7

关键词:C语言;指针;应用规律

1 C语言指针中的两个概念区分

⑴数组指针和指针数组。指向数组的指针称为数组指针,数组的特点是数组中每个元素类型相同,且在内存中连续存放,只要数组指针向一个成员,则可顺次推算出其余成员的地址,因此通过数组指针可将数组中的所有元素间接访问;指针数组是指一组类型相同的指针组成的数组,其与数组指针最大的不同是,指针数组在指针的数量上有所改变,它由一个指针演变到一组同类指针。

⑵指针函数与函数指针。指针函数是返回值为指针的函数,指针函数打破了其它高级语言中的指针、数组不能作为返回值的局限,体现了C语言程序的灵活性。值得注意的是,若使用变量的地址作为函数的返回值,此地址所对应的变量空间如果被释放,其中的数据可能发生了变化,那么就不能达到正常的传送数据的目的,另外在使用指针函数时,接受函数值的变量也必须为指针,且应与返回值的类型相同。指针变量可以指向整型变量、字符串变量、也可以指向函数的入口地址和指针为函数指针。函数指针是一个高深的概念,函数指针的作用是函数间传递函数,指针函数与函数指针的相似之处在于两者都跟函数有关,不同之处在于指针函数中的指针指向函数出口,而函数指针中的指针指向函数入口,二者指向方向的差异是两者间的最大区别。

2 指针一些主要应用的基本规律

我们已经看到,所谓指针的概念跟内存有着紧密的联系。对指针的理解,本质上是对内存的理解,毕竟内存是生命空间。而指针的一些主要应用,也的确凸现了这一点,让无数学生头痛不已的链表,结合一些内存相关函数,指针游走于内存当中,充分地表现自己。

⑴定义指针后,必须将其初始化。可以用做给指针变量初始化的有变量的地址,另一个指针变量,数组名,函数名等。需要注意的是动态内存分配时,使用之前将其初始化为NULL。

指针在定义之后,如果没有明确赋值,那么和其他变量类似,其内部的地址值是随机的。此时指针指向的空间中的数据意义是不可预测的,一般成为野指针。我们知道在C语言中,指针是可以指向CPU可访问内存的任意位置,这客观上造成了错误地指向系统数据或其他有用数据的可能。而且C语言一般不做诸如数组越界或野指针的检查。NULL在一般的编译器中都都在某编译系统的头文件的中做了宏定义,通常情况下被定义为0L。0L的含义是:“值为0的整数常量表达式”。大多数操作系统将0L开始的一段内存预留出来做为无用的空间,指针在没有明确使用的情况下指向此处,可以保护系统。

⑵如果利用指针动态申请内存,使用过后注意释放内存,否则会造成内存泄漏。程序的内存空间一般分为四个逻辑区域,即代码区、全局数据区、栈区和堆区。当程序执行的时候,其可执行文件作为二进制机器指令被调入内存顺序存放,以实现所谓的自动执行。栈区主要是函数调用的活动区域,为函数分配局部动态变量等,函数调用结束后系统会自动收回内存。全局数据区存放的是静态和全局变量,随着程序的消亡而自动收收回内存。一般我们常说的内存泄漏是指堆内存的泄漏。堆内存是指程序从堆区中分配的,大小任意的(内存块的大小可以在程序运行期决定),是由程序员自己需要时申请,使用完后也必须用程序代码显式释放的内存。应用程序一般使用mal-loc,realloc,new等函数从堆中分配到一块内存(通过指针变量记录 该段内存的首地址来实现),使用完后,程序必须负责相应的调用free或delete释放该内存块,否则,这块内存就不能被再次使用,我们就说这块内存泄漏了。使用指针时,在赋值等重要操作之前要注意观察指针的当前指向, 做适当的显式判断,动态申请内存块,尤其要保留其指针初值,以便释放内存。

如下列代码段:

如果缺少free(str)语句,将造成1000个字节的堆内存泄漏。引起内存泄漏的主要原因在于内存分配后指向内存的指针丢失了。在堆里动态申请内存以后,如果擅自修改指针的指向,就会早成野指针而迷失方向,无法回收内存,引起泄漏。

⑶指针所指向的内存回收以后,也要清除指针,安全起见将其重置为NULL。

如下列代码段:

如果缺少语句str=NULL,后果无法预料,极度危险。因为free(str):之后,str成为野指针,其指向不明,if(str!=NULL)语句不起作用。此时,str指向的存储区里是什么?我们不知道。它有可能是一个非常重要的数据,甚至可能是一条程序源代码(指针指向代码区某段)。如果此时指针不幸指向系统核心数据区,给它赋值一个字符串“word”,将会引起整个计算机系统崩溃。在用指针访问数组的时候,也要注意不要超出数组的低端和高端界限,否则也会造成类似的错误。

[参考文献]

[1]谭浩强.C语言程序设计[M].北京:清华大学出版社,1999.

c语言指针篇8

关键词:C语言 计算机 软件编程 编程方法优化

1、C语言概述

C语言本身具备着较为优越的功能,而其本身拥有的兼具汇编语言和高级语言特点的能力,也是C语言能够在今天的计算机编程中得到广泛应用的原因所在。C语言发展到今天,已成为各种计算机编程语言的基础,而其具备的灵活方便、简洁紧凑、适用于多种操作系统、可自由书写等特点,更为C语言的广泛应用提供了坚实基础。

2、基于C语言的计算机编程技术

2.1 C语言中的函数

在基于C语言的计算机编程技术中,由于具体的编程过程需要分为若干个模块,这就使得其中每一个模块功能的实现,都需要由函数完成。对于基于C语言的计算机编程技术来说,其本身需要应用多种特有的函数,而这类函数的应用过程,相关编程人员需要进行命名、定义参数名以及定义返回值类型等操作,这样才能够顺利完成基于C语言的模块功能设计。当然由于计算机技术的不断发展,编程人员大多数时候都无需手动输入C语言相关的函数,只需要在编程时输入“#include”指令,就可以使用定义好的函数库完成具体的编程操作。

2.2 变量存贮器类型的合理定义

在基于C语言的计算机编程技术中,对变量存贮器类型进行合理定义也是这一技术的重要组成部分。具体来说,基于C语言的计算机编程往往需要应用不同类型的变量存贮器,而不同的变量存贮器对于编译代码的执行效率也不尽相同,为此编程人员可以在子程序模块编程中尽量选择局部变量存贮器,整个程序模块的编程则可以选择全局变量存贮器,这样就能够较好实现基于C语言计算机编程过程中变量存贮器类型的合理定义。

2.3 算法技巧及位操作

对于基于C语言的计算机编程来说,算法称得上是这一编程语言的灵魂所在,这就使得编程人员在应用C语言进行计算机编程时,必须掌握一定算法技巧,对于基于C语言的计算机编程来说,其本身具备着自然语言和流程图两种算法表示方法。值得注意的是,在应用流程图对基于C语言的计算机编程算法表示中,编程人员能够基于这一表示了解流程图符号的含义,这样就能够保证其较好的进行基于C语言的计算机编程算法技巧应用。

2.4 多重\算次序

在基于C语言的计算机编程中,C语言本身对于变量多重运算求值顺序没有形成统一的规定。有过应用C语言编程经验的人就会了解到,不同C语言编译系统存在着细微差别,而很多C语言编译系统在多重运算次序上存在着一定差别。据笔者调查得知,在我国当下基于C语言的计算机编程中,参数求值顺序从右到左最为常见,这就使得基于C语言的计算机编程多重运算次序大多为先运算最后面,依次运算前面,这种基于C语言的计算机编程多重运算次序选择有着较好的可读性和移植性。

2.5 指针用法

对于基于C语言的计算机编程来说,指针用法也是这一编程的重要环节,在论述这一环节前,首先需要了解基于C语言的计算机编程中指针变量。结合相关文献资料笔者发现,定义指针变量时必须对其进行初始化,否则存储空间操作很容易出现严重错误。值得注意的是,编程人员还可以通过加减数值移动指针位置,完成具体的指针计算。此外,应用函数库中的 void 函数,就能够实现指针变量的定义,最终实现将任意数据类型的地址赋给指针变量。

3、基于C语言的编程方法优化

结合上文内容,对基于C语言的计算机编程技术有了较为直观的认识,而为了保证基于C语言的计算机编程技术能够更好发挥自身作用,笔者结合自身多年编程经验与相关文献资料,对基于C语言的计算机编程方法优化进行了详细论述,希望这一论述能够为相关C语言计算机编程从业者带来一定启发。

3.1 优化函数调用

对于基于C语言的计算机编程技术来时,想要实现自身的优化,优化函数调用属于较为有效的方法。具体来说,在基于C语言的计算机编程技术函数调用的优化中,首先需要禁止函数调用传递结构,之所以需要禁止传递结构的函数调用,主要是由于函数调用传递结构会将整个结构复制到堆栈,这就将大量占用堆栈空间,最终加重整个系统的负担,而为了解决不能函数调动传递结构这一影响,可以采用结构指针解决这一问题,这样就顺利实现了基于C语言的计算机编程技术函数调动优化。

对于基于C语言的计算机编程技术来说,其本身具备着多种能够提高自身编程效率的库函数,但这些函数往往具备着代码量大、效率低的缺点,这种缺点之所以出现,主要是由于库函数需要保证自身的广泛适用性,所以编程人员在具体的工作中,就可以结合库函数,自己设计一段函数程序,这样也能够较好实现函数调用的优化。

3.2 指针在数组中使用

对于基于C语言的计算机编程技术来说,想要实现自身技术的优化,就可以将指针在数组中使用,这样就能够大大提高程序的运行效率。具体来说,一般基于C语言的计算机编程需要多次计算数组地址来获得数组中相应的每一个数值,这就大大影响了程序的运行效率,所以笔者建议将指针变量直接指向数组中元素,这样就能够较好实现基于C语言的计算机编程技术优化。

3.3 优化循环语句

为了能够实现基于C语言的计算机编程技术优化,对循环语句进行优化也是优化的较好选择。在基于C语言的计算机编程中,某些重要的循环直接关系着程序运行速度,所以笔者建议将有些在运算时并不需要加入循环变量的任务置于循环外,这样就能够较好实现循环的优化,大大提高程序的运行速度并降低CPU 的负担。

4、结语

在本文就基于C语言的计算机编程技术展开的研究中,笔者详细论述了C语言概述、基于C语言的计算机编程技术以及基于C语言的编程方法优化,希望这一论述内容能够在一定程度上推动我国计算机编程技术的发展,并为于C语言的学习者带来一定帮助。

参考文献:

[1]刘秀明. 基C语言的计算机软件编程实验研究[J].电子技术与软件工程 ,2014(5):263.

[2]田智. 基于计算机软件开发的 JAVA 编程语言分析[J].硅谷 ,2014(19):59.

上一篇:视听语言范文 下一篇:vb语言范文