关于C语言指针函数指针数组的问题

  摘要:C语言中指针是它的精髓部分,也是它的重要特色。正确灵活地运用指针可以有效地表示复杂的数据结构;能够方便地使用字符" />
免费阅读期刊
论文发表、论文指导
周一至周五
9:00&22:00
C语言指针中的几个常见错误及纠正方法
  摘要:C语言中指针是它的精髓部分,也是它的重要特色。正确灵活地运用指针可以有效地表示复杂的数据结构;能够方便地使用字符串;能动态分配内存;能直接处理内存地址;有效而方便地使用数组等。掌握指针的应用,可以使程序简洁、紧凑、高效。每个学习和使用C语言的人,都应当深入地学习和掌握指针。 中国论文网 /9/view-5455781.htm  关键词:C语言;指针;数组   C语言指针的应用非常灵活,使用它也存在者危险。对熟练的人来说,正确的使用它可编写出颇具特色且质量优秀的程序,实现用其它高级语言难以实现的功能。但如果使用不当,很容易出错。有些隐藏较深的错误很难发现和排除,因此在学习C语言时,理解和使用指针非常重要。以下通过几个实例,说明指针编程时的几个常见错误和改正办法。   一、 使用未初始化的指针   C语言中指针是用于存放变量地址的。指针变量是C语言中的一个特殊类型的变量。指针变量定义后应确定其指向。在没有确定指针的具体指向前,指针变量的内容是随机的地址,盲目地引用将十分危险。   例如:下列程序用于将键入的两个整数按大小顺序输出。   swap(p1,p2)   int*p1,*p2;   {int*p; *p=*p1; *p1=*p2; *p2=*p;   }   main()   {   int a,b;   int *pointer1,*pointer2;   scanf(“%d,%d”,&a,&b);   pointer=&a;pointer2=&b;   if(a   printf(0%d,%d0,a,b);   }   这里swap函数的功能是实现指针p1,p2所指单元内容互换,其中以*p为中间变量,这就犯了未定向就使用的错误,根据C编译系统的规则,当swap函数发生调用时,系统仅给指针p分配一个内存单元。而这一内存里存放的地址未定。它可能是操作系统或其它用户区的某一内存地址,当运行程序时,很可能使不属于本程序的某个内存内容被修改,从而造成整个系统的崩溃。对swap函数可修改为如下形式:   swap(p1,p2)   int*p1,*p2;   {intp; p=*p1; *p1=*p2; *p=p; }   二、指针变量所指向的变量类型与其定义的类型不符   定义指针变量的一般格式为:   类型说明符 *指针变量名;   其中类型说明符规定的是指针变量所指向的变量的类型。C语言规定一个指针变量只能指向同一类型的变量。例如:   main()   {   float x;   int *p;   p=&x;   }   x与*p数据类型不符。因x的类型是单精度实型的,而指针p是指向整型变量的指针,应将语句改为: float *p;   又如:   main()   {   int *p;   p=malloc(sizeof(mt));   }   malloc()函数的功能是分配内存存储空间,并返回一个指向分配空间起始单元的指针。一般系统中,此指针为char型或void型,因此与指针变量p类型不符。应对malloc函数做强制转换,改为: p=(int)malloc(sizecf(int));   三、指针的错误赋值   指针变量的值是某个数据对象的地址,只允许取正的整数值,而千万不能将它与整数类型变量混淆。指针赋值时在赋值号右边的应是变量地址,且是所指变量地址。   例如:   main() {   int i=5;   int *p;   p=i; }   语句p=i中的赋值是错误的,应改为:   p=&i;   又如:   main() {   int max();   int *pointer();   pointer=max(); }   语句的含义是将int型函数值赋给了指针变量,是错误的写法,应直接写函数名就行了,即:p=max;   四、结束语   指针是C语言中极重要的概念,是其特征功能之一,也是C语言程序设计的难点。本文只对一部分常见问题给出正确使用指针的方法。
转载请注明来源。原文地址:
【xzbu】郑重声明:本网站资源、信息来源于网络,完全免费共享,仅供学习和研究使用,版权和著作权归原作者所有,如有不愿意被转载的情况,请通知我们删除已转载的信息。
xzbu发布此信息目的在于传播更多信息,与本网站立场无关。xzbu不保证该信息(包括但不限于文字、数据及图表)准确性、真实性、完整性等。没有更多推荐了,
不良信息举报
举报内容:
C语言的指针函数和函数指针有什么区别
举报原因:
原文地址:
原因补充:
最多只允许输入30个字
加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!c语言中的指针到底有什么用呀?
我是一名,是正学C语言,对于指针这方面,我已经学过了,可是我还是不会,我搞
我是一名,是正学C语言,对于指针这方面,我已经学过了,可是我还是不会,我搞不懂指针到底有什么用,而且我也不会使用,我快要做课程设计了,老师说如果指针没学好的话.根本做不好课程设计,我好担心.哪位好心的朋友能够帮帮我呀.谢谢.
指针是c的精髓//---- 转载--指针详解
原著: 什么是指针?
和其它变量一样,指针是基本的变量,所不同的是指针包含一个实际的数据,该数据代表一个可以找到实际信息的内存地址。这是一个非常重要的概念。许多程序和思想依靠指针作为他们设计的基础。
怎样定义一个指针呢?除了你需要在变量的名称前面加一个星号外,其它的和别的变量定义一样。举个例子,以下代码定义了两个指针变量,它们都指向一个整数。
int* pNumberO
int* pNumberT
注意到两个变量名称前的前缀.....
指针是c的精髓//---- 转载--指针详解
原著: 什么是指针?
和其它变量一样,指针是基本的变量,所不同的是指针包含一个实际的数据,该数据代表一个可以找到实际信息的内存地址。这是一个非常重要的概念。许多程序和思想依靠指针作为他们设计的基础。
怎样定义一个指针呢?除了你需要在变量的名称前面加一个星号外,其它的和别的变量定义一样。举个例子,以下代码定义了两个指针变量,它们都指向一个整数。
int* pNumberO
int* pNumberT
注意到两个变量名称前的前缀’p’了么?这是一个惯例,用来表示这个变量是个指针。
现在,让我们将这些指针实际的指向某些东西:
pNumberOne = &some_
pNumberTwo = &some_other_
‘&’符号应该读作”什么什么的地址”,它返回一个变量在内存中的地址,设置到左侧的变量中。因此,在这个例子中,pNumberOne设置和some_number的地址相同,因此pNumberOne现在指向some_number。
现在,如果我们想访问some_number的地址,可以使用pNumberOne。如果我们想通过pNumberOne访问some_number的值,那么应该用*pNumberOne。这个星号表示解除指针的参照,应该读作“什么什么指向的内存区域”。
到现在我们学到了什么?举个例子
哟,有许多东西需要理解。我的建议是,如果你有哪个概念没有弄清楚的话,那么,不妨再看一遍。指针是个复杂的对象,可能需要花费一段时间来掌握它。
这儿有一个例子示范上面所将的概念。这是用C写的,没有C++扩展。
#include &stdio.h&
void main()
// 申明变量
nNumber = 15;
pPointer = &nN
// 输出nNumber的值
printf(&nNumber is equal to : %d\n&, nNumber);
// 通过pPointer修改nNumber的值
*pPointer = 25;
// 证明nNumber已经被改变了
// 再次打印nNumber的值
printf(&nNumber is equal to : %d\n&, nNumber);
通读一遍,并且编译样例代码,确信你理解了它为什么这样工作。如果你准备好了,那么继续。
一个陷阱!
看看你能否发现下面这段程序的毛病:
#include &stdio.h&
void SomeFunction();
nNumber = 25;
//将pPointer指向nNumber
pPointer = &nN
void main()
SomeFunction(); //用pPointer做些事情
// 为什么会失败?
printf(&Value of *pPointer: %d\n&, *pPointer);
这段程序先调用SomeFunction函数,该函数创建一个叫做nNumber的变量,并将pPointer指向它。那么,问题是,当函数退出时,nNumber被删除了,因为它是一个局部变量。当程序执行到局部变量定义的程序块以外时,局部变量总是被删除了。这就意味着,当SomeFunction函数返回到main函数时,局部变量将被删除,因此pPointer将指向原先nNumber的地址,但这个地址已经不再属于这段程序了。如果你不理解这些,那么重新阅读一遍关于局部变量和全局变量的作用范围是明智的选择。这个概念也是非常重要的。
那么,我们如何解决这个问题呢?答案是使用大家都知道的一个方法:动态分配。请明白C和C++的动态分配是不同的。既然现在大多数程序员都使用C++,那么下面这段代码就是常用的了。
动态分配可以说是指针的关键所在。不需要通过定义变量,就可以将指针指向分配的内存。也许这个概念看起来比较模糊,但是确实比较简单。下面的代码示范如何为一个整数分配内存:
第一行申明了一个指针pNumber,第二行分配一个整数内存,并且将pNumber指向这个新内存。下面是另一个例子,这次用一个浮点数:
double *pD
动态分配有什么不同的呢?当函数返回或者程序运行到当前块以外时,你动态分配的内存将不会被删除。因此,如果我们用动态分配重写上面的例子,可以看到现在能够正常工作了。
#include &stdio.h&
void SomeFunction()
// make pPointer point to a new integer
pPointer =
*pPointer = 25;
void main()
SomeFunction(); // make pPointer point to something
printf(&Value of *pPointer: %d\n&, *pPointer);
通读一遍,编译上面的代码,确信你已经理解它是如何工作的。当调用SomeFunction时,分配了一些内存,并且用pPointer指向它。这次,当函数返回时,新内存就完整无缺了。因此pPointer仍旧指向有用的东西。这是因为使用了动态分配。确信你已经理解它了。那么继续向下看,了解为什么上面的程序还会有一系列的错误。
内存分配和内存释放
这里有一个问题,可能会变得十分严重,虽然它很容易补救。这个问题就是,虽然你用动态分配可以方便的让内存完整无缺,确实不会自动删除,除非你告诉计算机,你不再需要这块内存了,否则内存将一直被分配着。因此结果就是,如果你不告诉计算机你已经使用完这块内存,那么它将成为被浪费的空间,因为其它程序或者你的应用程序的其它部分不能使用这块内存。最终将导致系统因为内存耗尽而崩溃。因此这个问题相当重要。内存使用完后释放非常容易:
需要做的就是这些。但是你必须确定,你删除的是一个指向你实际分配的内存的指针,而不是其它任何垃圾。尝试用delete已经释放的内存是危险的,并且可能导致程序崩溃。
这里再次举个例子,这次修改以后就不会有内存浪费了。
#include &stdio.h&
void SomeFunction()
// make pPointer point to a new integer
pPointer =
*pPointer = 25;
void main()
SomeFunction(); // make pPointer point to something
printf(&Value of *pPointer: %d\n&, *pPointer);
只有一行不同,但这行是要点。如果你不删除内存,就会导致“内存泄漏”,内存将逐渐减少,除非应用程序重新启动,否则将不能再生。
向函数传递指针
传递指针给函数非常有用,但不容易掌握。如果我们写一个程序,传递一个数值并且给它加上5,我们也许会写出如下的程序:
#include &stdio.h&
void AddFive(int Number)
Number = Number + 5;
void main()
int nMyNumber = 18;
printf(&My original number is %d\n&, nMyNumber);
AddFive(nMyNumber);
printf(&My new number is %d\n&, nMyNumber);
但是,程序中函数AddFive的参数Number只是变量nMyNumber的一个拷贝,而不是变量本身,因此,Number = Number + 5只是为变量的拷贝增加了5,而不是最初的在main()函数中的变量。当然,你可以运行程序,以证明这一点。
为了将值传递出去,我们可以传递这个变量的指针到函数中,但我们需要修改一下函数,以便传递数值的指针而不是数值。因此将void AddFive(int Number)修改为void AddFive(int *Number),增加了一个星号。下面是修改了的函数,注意,我们必须确认传递了nMyNumber的地址,而不是它本身。这通过增加&符号来完成,通常读作“什么什么的地址”。
#include &stdio.h&
void AddFive(int* Number)
*Number = *Number + 5;
void main()
int nMyNumber = 18;
printf(&My original number is %d\n&, nMyNumber);
AddFive(&nMyNumber);
printf(&My new number is %d\n&, nMyNumber);
大家可以试着自己做个例子来实验一下。注意在AddFive函数中Number变量前那个重要的星号。只是必须的,用来告诉编译器我们想将5加到变量Number指向的数值,而不是将5加到指针本身。
关于函数最后需要注意的是你也可以返回一个指针。比如:
int * MyFunction();
在这个例子中,MyFunction函数返回一个指向整数的指针。
关于指针还有两个需要注意的问题。其中一个是结构或者类。你可以如下定义一个类:
class MyClass
然后,你可以如下方式定义一个类变量:
你应该已经知道这些了,如果还不知道的话,那么再将上面的内容读一遍。定义MyClass的指针应该这么写:
然后你需要分配内存,并将指针指向这个内存
thing = new MyC
问题来了,你如何使用这个指针呢?一般的,我们写thing.m_Number,但你不能对指针用’.’操作,因为thing不是一个MyClass对象。只是指向一个MyClass对象的指针。因此,指针thing不包含m_Number这个变量。只是它指向的结构中包含这个变量。因此,我们必须使用一个不同的协定,用-&取代’.’。以下是一个例子:
class MyClass
void main()
MyClass *pP
pPointer = new MyC
pPointer-&m_Number = 10;
pPointer-&m_Character = 's';
数组的指针
你也可以构造一个指向数组的指针,如下:
pArray = new int[6];
将创建一个叫做pArray的指针,指向一个包含6个元素的数组。另一种构造的方法是使用动态分配,如下:
int MyArray[6];
pArray = &MyArray[0];
注意,你这里也可以不用&MyArray[0],而直接使用&MyArray取代。当然,这仅仅适用于数组。
使用指向数组的指针
一旦你有了指向数组的指针,那么如何使用它呢?现在假设你有一个指向整数数组的指针,那么指针开始时将指向第一个整数。举例如下:
#include &stdio.h&
void main()
int Array[3];
Array[0] = 10;
Array[1] = 20;
Array[2] = 30;
pArray = &Array[0];
printf(&pArray points to the value %d\n&, *pArray);
将指针移到指向数组的下一个值,可以用pArray++。也许你也可以猜出来了,我们可以用pArray+2的方式将指针向后移动两个位置。要注意的问题是,你自己必须知道数组的上限是多少(例子中是3),因为编译器不能检查你是否将指针移到了数组以外,因此你可以很容易的将系统搞崩溃了。以下是个例子,显示我们设置的三个值:
#include &stdio.h&
void main()
int Array[3];
Array[0] = 10;
Array[1] = 20;
Array[2] = 30;
pArray = &Array[0];
printf(&pArray points to the value %d\n&, *pArray);
printf(&pArray points to the value %d\n&, *pArray);
printf(&pArray points to the value %d\n&, *pArray);
你也可以使用pArray-2这样的方式来向前移动2个位置。不管是加或者减,你必须保证不是对指针所指向的数据的操作。这种操作指针和数组的方式在循环中是最常用的。例如for和while循环。
另外要提的是,如果你有一个指针比如int pNumberSet,你也可以把它当成数组。例如pNumberSet[0]等于*pNumberSet,并且pNumberSet[1]等于*(pNumberSet+1)。
对于数组,还有一点要注意的,如果你用new为数组分配内存,比如:
pArray = new int[6];
你必须用以下方式进行删除:
delete[] pA
注意delete后的[],它告诉编译器,这是删除整个数组,而不仅仅是第一个元素。对于数组你必须使用这种方法,否则就会有内存泄漏。
一条要注意的:你不能删除不是用new分配的内存。比如以下例子:
void main()
int *pNumber =
delete pN // wrong - *pNumber wasn't allocated using new.
掌握指针就是掌握了一种处理数据的方法,举个例子,比如你要访问一个变量,你可以直接访问它,如果有这么一
类似问题换一批
相关推荐换一换
有问题 @ 爱问Powered by iask.com
举报原因(必选):
广告或垃圾信息
不雅词句或人身攻击
激进时政或意识形态话题
侵犯他人隐私
其它违法和不良信息深入理解C语言中的指针
深入理解C语言中的指针:
指针是一个特殊的变量,它里面存储的数值被解释成为内存里的一个地址。
要搞清一个指针需要搞清指针的四方面的内容:
1、指针的类型,从语法的角度看,你只要把指针声明语句里的指针名字去掉,剩下的部分就是这个指针的类型。这是指针本身所具有的类型。
2、指针所指向的类型,当你通过指针来访问指针所指向的内存区时,指针所指向的类型决定了编译器将把那片内存区里的内容当做什么来看待。从语法上看,你只须把指针声明语句中的指针名字和名字左边的指针声明符*去掉,剩下的就是指针所指向的类型。
3、指针的值或者叫指针所指向的内存区,指针的值是指针本身存储的数值,这个值将被编译器当作一个地址,而不是一个一般的数值。在32位程序里,所有类型的指针的值都是一个32位整数,因为32位程序里内存地址全都是32位长。
4、还有指针本身所占据的内存区。指针本身占了多大的内存?你只要用函数sizeof(指针的类型)测一下就知道了。在32位平台里,指针本身占据了4个字节的长度。指针本身占据的内存这个概念在判断一个指针表达式是否是左值时很有用。
已投稿到:
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。}

我要回帖

更多关于 c语言函数指针 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信