标题:青梅浅谈之C语言指针
只看楼主
青梅煮酒
Rank: 2
等 级:论坛游民
帖 子:12
专家分:10
注 册:2012-3-17
结帖率:0
已结贴  问题点数:20 回复次数:26 
青梅浅谈之C语言指针

讲师:青梅煮酒

    指针是C语言独有的也是学习C语言的重点,要学好C语言,必须将指针十分了解,才能很好的利用C语言来为我们服务。你是不是觉得指针很难学?不,不要有这样的想法,下面就由我来想大家讲解C指针,从浅至深。

一、什么是变量
首先先定义一个变量a,其内部结构如下图所示:
貌似不能插入图片
    一个变量有三个属性,分别是:名称、地址、内容,名称为我们声明变量时为变量赋予的名字;地址是系统随机分配的一个内存编号;内容是我们赋予变量的值。我们来分析如下代码:
int main (void)
{
    int a;      
    a = 10;
    return 0;
}
1.  int a; 我们声明一个名称为a的变量,系统在内存中随机找到一块空闲的空间,并将使用权限交于软件,此时a变量的名称与地址都已定义,其值暂未定义,目前是垃圾值。
2.  a = 10; 将变量a的值定义为10。
    由此可见在一个变量的定义时,我们认为可以操控其名称与值,但地址是由系统随机控制的。这里要注意的是不要将变量的这三个属性混淆,认清这一点有助于我们对指针的学习。

二、什么是指针变量
    所谓的指针就是指地址,所谓指针变量就是用来专门存放地址的变量。我们定义的一般变量可以存放如:字符、数字等值,而指针变量只能存放变量的地址,并且指针变量的类型应为所所指向变量的类型,如:你不可以创建一个整型变量a,在创建一个浮点型指针,将其指向变量a(明白这一点有助于对结构的学习)。
    指针变量和一般变量向同,也由三个属性,其分别为:名称、地址、内容,指针变量的内容存放的是地址。这里应注意的是不要将指针变量的地址与内容混淆,指针变量的地址是其自身的地址,而内容是别的变量的地址(如指针变量的内容指向自己的地址,这里不讨论)。
1.如何定义指针变量
int main(void)
{
       int a;
       int* p;
       p = &a;
       *p = 10;
       printf("%d\n",a);
       return 0;
}
1.  int a;    创建一个变量a,其类型为int型,
2.  int* p;   创建一个指针变量p,其值为垃圾值
3.  p = &a;   将变量a的地址赋予指针变量p,
4.  *p = 10;  修改指针变量p所指向的变量内容。
详解:
    第2步创建了一个指针变量p,方法为所要指向变量的数据类型加“*”,注意的是其创建的指针变量是p,而不是*p,其类型为int*型。这时的指针变量的内容为垃圾值,第3步将为指针变量赋值p = &a;,将a的地址发送给p。
2.如何使用指针变量

    指针变量的使用与一般变量有所不同,首先我们要明白为何声明一个指针变量?其实声明指针变量的作用是用来控制一般变量,所以我们不能像一般变量那样使用指针变量。判断下面两行加粗代码:
int main(void)
{
       int a;
       int* p;
       p = &a;
       p = 10;
       *p = 10;
       printf("%d\n",a);
       return 0;
}
详解:
    指针变量p只接受地址,所以p = 10;,是错误的。而在上一步p = &a;,中我们已将a的地址发送给p,为何要将a的地址发送给p呢?我们的目的是通过指针变量p来控制a,那么怎么才能达到目的呢?我们使用“*”加p的方式,就可以控制a,这时候*p就等同于a变量,编译以上代码,查看结果。
    一个指针变量,不论其为何类型,都只占4个字节,原因是指针变量只储存任何数据的前4个字节的地址,其长度是由类型控制的。如:定义一个double a;变量,其指针只保存其前4个字节的地址,后4个字节时由double来控制,所以说我们定义的指针变量其类型要与其指向的变量类型形同。

三、指针与数组
首先分析(式一):
void tex (int* p, int i)
{
    p[2] = 10;
}
int main(void)
{
    int n;
    int a[5] = {1, 2, 3, 4, 5};
    tex(a, 5);
    printf("%d",a[2]);
    return 0;
}
    上式时定义了一个数组a,然后通过函数tex将a第三个元素的值进行修改后输出。你是不是有这样一个问题:p[2] = 10;不对吧,怎么不是*p[2] = 10;?这里是难点也是重点,当初我自学时也卡到了这里,不过也很简单,主要是我们将一个概念没有弄明白。
1.什么是数组
    我们在以前学习数组时,由于并没有接触指针,所以数组的内部结构并没有学习,那么现在我们就来重新认识一下数组。
    数组就是将数据连续的储存在内存中,这里的关键词是连续!C语言中规定一个数组的数组名就是其第一个元素的地址,由此我们可以知道a实质是a[0]的地址即a == &a[0]。那么结合我们所学的指针,数组a的第一个元素就是*(a),第二个元素是*(a+1),以此类推。
int main(void)
{
    int i;
    int a[5];
    *(a) = 1;
    *(a+1) = 2;
    *(a+2) = 3;
    *(a+3) = 4;
    *(a+4) = 5;
    for (i=0; i<5; ++i)
    {
        printf("%d",a[i]);
    }
    return 0;
}
    将上式输入VC++6.0中是能成功编译的,同时为方便使用C语言又规定我们可以使用下标“[]”,即*(a) == a[0],*(a+1) == a[1]。所以对于数组来说,其数组名本来就是一个地址,C语言规定了可以用下标的形式来表示各个元素,所以在(式一)中我们使用的是p[2] = 10; 而不是*p[2] = 10;。我们所使用的数组就是指针的一种形式,这一点在动态数组中将充分的体现出来。
注:*(a+1)其等同于 *(a + (int*1))  地址跳向下一个元素。

四、指针与结构体
    所谓结构体就是自定义数据类型,以下为结构体中指针的使用,其中p->personnel = 20;等价于(*p).personnel = 20;,p->等同于(*p).。在编程中同常采用第二种形式书写,希望大家吃透以下代码,这有利于以后对链接的学习。
# include <string.h>
struct item
{
     char name[50];
     int personnel;
     double invest;
};
int main(void)
{
     struct item one;
     struct item* p = &one;
     strcpy((*p).name,"calzada");
     (*p).personnel = 20;
     (*p).invest = 20.5;
      //strcpy(p->name,"calzada");
      //p->personnel = 20;
      //p->invest = 20.5;
      return 0;
}
    上面代码中struct item{ ….. }是创建了一个数据类型而不是变量,其类型为struct item型。struct item one;是创建了名为one的变量,其数据类型为struct item,所以指向one的指针也必须为struct item型。结构体变量不能参与算数用算,只能相互赋值。

五、指针的指针
先阅读下列式子
       int main (void)
{
       int* p;
       printf("%0x\n",p);
       int** q = &p;
       int i;
       printf("%0x\n",&i);
       *q = &i;
       printf("%0x\n",p);
       return 0;
}
    上式是将一个指针变量p的地址发送给一个指针变量q,然后通过指针变量q修改指针变量p的内容(所指向的地址)。由于指针变量p为int*类型,所以指向它的指针变量q也应为int*类型再加“*”,即为int**类型。*q = &i;等同于p = &i;。

结束语
    学好指针对日后C语言的学习事关重要,C语言是面向过程的语言,其实质是对内存的操作,而指针为我们提供了控制内存的方法。
    首先感谢您的阅读,本文内容为我个人的见解所以名为:青梅浅谈,本文章为原创,受著作权保护,如需引用请指明出处!谢谢!

 

 

                                                                                   青梅煮酒

                                                                               2012年3月6日19:54:26

 

 

 

 

 

 

 

 

 
搜索更多相关主题的帖子: void 讲师 插入图片 C语言 
2012-03-17 14:03
wsws23
Rank: 3Rank: 3
等 级:论坛游侠
帖 子:105
专家分:107
注 册:2012-3-13
得分:1 
楼主自己整理的吗  ?
2012-03-17 14:37
青梅煮酒
Rank: 2
等 级:论坛游民
帖 子:12
专家分:10
注 册:2012-3-17
得分:0 
自己写的,如何?
2012-03-17 14:49
Devil_W
Rank: 10Rank: 10Rank: 10
等 级:青峰侠
威 望:9
帖 子:1160
专家分:1797
注 册:2009-9-14
得分:1 
以下是引用青梅煮酒在2012-3-17 14:49:50的发言:

自己写的,如何?

你能告诉我32位机器 可以有8字节的指针吗?
2012-03-17 14:50
wsws23
Rank: 3Rank: 3
等 级:论坛游侠
帖 子:105
专家分:107
注 册:2012-3-13
得分:0 
回复 3楼 青梅煮酒
我只能说 自愧不如  我们都天天老师讲还听不懂呢
2012-03-17 14:58
lmxy1990
Rank: 2
等 级:论坛游民
帖 子:21
专家分:23
注 册:2011-12-19
得分:1 
问一个问题,指针不只是用来存放变量地址的,指针就是地址,包括文件,函数。。。。
还有,我觉的int *p;是指针变量,而p是指针变量名。*p是指针变量。
2012-03-17 15:06
lmxy1990
Rank: 2
等 级:论坛游民
帖 子:21
专家分:23
注 册:2011-12-19
得分:0 
回复 6楼 lmxy1990
另外,我觉得指针变量也是变量。
只是它是一种存放地址的变量。
所以,这里我明白。但是在调用的时候,变量使用的是变量名,而指针使用的是指针变量名。这容易出点小问题,就是我们说的变量与变量名是相等的。例如,我们说的int a;那么我们称变量a,a也是变量名。但是指针不一样,函数调用用的是变量名,而不是变量。所以在调用指针时候,例如:int a,*p;fun(a,p);而不是*p,我一直在这里记不大清,所以就这样去记忆。。。。
2012-03-17 15:13
zaixuexi
Rank: 12Rank: 12Rank: 12
来 自:上海
等 级:火箭侠
威 望:8
帖 子:858
专家分:3233
注 册:2010-12-1
得分:1 
回复 4楼 Devil_W
null

[ 本帖最后由 zaixuexi 于 2012-3-17 20:00 编辑 ]

技术问题,请不要以短消息方式提问
2012-03-17 15:16
Devil_W
Rank: 10Rank: 10Rank: 10
等 级:青峰侠
威 望:9
帖 子:1160
专家分:1797
注 册:2009-9-14
得分:0 
以下是引用zaixuexi在2012-3-17 15:16:20的发言:

又在show你智商下限?

不能跟你比,你智商没下限。
2012-03-17 15:25
wsws23
Rank: 3Rank: 3
等 级:论坛游侠
帖 子:105
专家分:107
注 册:2012-3-13
得分:0 
我觉的int *p;是指针变量,而p是指针变量名。*p是指针变量
int* p是指针变量,*p相当于变量(指针所指的变量)。
2012-03-17 15:25



参与讨论请移步原网站贴子:https://bbs.bccn.net/thread-363453-1-1.html




关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.071589 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved