首页
社区
课程
招聘
[原创]指针
发表于: 2015-12-29 09:37 5490

[原创]指针

2015-12-29 09:37
5490

发表于我的博客:http://www.cnblogs.com/zhenghongxin/p/4961832.html
概念

1 指针也是一个变量,做为指针变量的值是另一个变量的地址。指针存放的内容是一个地址,该地址指向一块内存空间

其一般形式为:

类型说明符  *变量名;
其中,*表示这是一个指针变量,变量名即为定义的指针变量名,类型说明符表示本指针变量所指向的变量的数据类型。

例如:    int *p1;
表示p1是一个指针变量,它的值是某个整型变量的地址。或者说p1指向一个整型变量。至于p1究竟指向哪一个整型变量,应由向p1赋予的地址来决定。

2 图例解释

int i = 10;//一个int变量,名字叫i
int *p;//定义了一个指向整数的指针变量

注意:

//在以下中
int i = 10;//一个int变量,名字叫i
int *p;//定义了一个指向整数的指针变量

//p = 10;//错误,不可以把一个整数直接赋值给指针变量.
//c语言当中每个变量都有自己的内存地址。&符号就是取变量地址操作符.

printf("%x",&i);     //输出i的16进制地址
printf("%d",*p);    //输出i的值
printf("%x",&*p);  //输出i的16进制地址
printf("%x",&p);    //输出p的地址,注意,指针也有自己的内存地址
printf("%x",p);      //输出i的16进制地址

切记,指针变量只能存放地址,不能将一个int型变量直接赋值给一个指针。

3 指针变量的引用

指针变量同普通变量一样,使用之前不仅要定义说明,而且必须赋予具体的值。未经赋值的指针变量不能使用,否则将造成系统混乱,甚至死机。指针变量的赋值只能赋予地址, 决不能赋予任何其它数据,否则将引起错误。在C语言中,变量的地址是由编译系统分配的,对用户完全透明,用户不知道变量的具体地址。

两个有关的运算符:

1)   &:取地址运算符。

2)   *:指针运算符(或称“间接访问” 运算符)。

C语言中提供了地址运算符&来表示变量的地址。

其一般形式为:

    &变量名;

如&a表示变量a的地址,&b表示变量b的地址。变量本身必须预先说明。

设有指向整型变量的指针变量p,如要把整型变量a 的地址赋予p可以有以下两种方式:

(1) 指针变量初始化的方法

  int a;

    int *p=&a;

(2) 赋值语句的方法

    int a;

    int *p;

p=&a;

不允许把一个数赋予指针变量,故下面的赋值是错误的:

int *p;

p=1000;

4 野指针

定义了一个指向int的指针变量;没有赋初值,就是个野指针,指向什么内存地址不知道

int *p3;

* 野指针的危害只是程序本身,不会影响到操作系统。

* 如果你做的是一个驱动程序或者内核代码,那么可能是致命的,操作系统崩溃

* 野指针也叫悬空指针,不能给野指针指向的内存区域赋值。

注意:一个指向NULL的指针,我们称之为空指针(也就是说野指针),意味着这个指针不指向任何一个变量。

5 无类型指针

定义一个指针变量,但不指定它指向具体哪种数据类型。可以通过强制转化将void *转化为其他类型指针,也可以用(void *)将其他类型指针强制转化为void类型指针。

void *p
在C语言当中,可以将任何一种地址赋值给void *指针

例如:

void *p4;//定义了一个无类型的指针。
p4 = &i;//可以将任意类型的地址赋值给void *
//p1 = p4;//(在C语言中可以将void *赋给任意类型的指针变量).但C++这个语句是非法的
6  指针变量作为函数参数

函数的参数不仅可以是整型、实型、字符型等数据,还可以是指针类型。它的作用是将一个变量的地址传送到另一个函数中。

例:输入的两个整数按大小顺序输出

复制代码
swap(int *p1,int *p2)
{int temp;
temp=*p1;
*p1=*p2;
*p2=temp;
}

main()
{
int a,b;
int *pointer_1,*pointer_2;
  scanf("%d,%d",&a,&b);
  pointer_1=&a;pointer_2=&b;
  if(a<b) swap(pointer_1,pointer_2);
  printf("\n%d,%d\n",a,b);
  }
复制代码
说明:

swap是用户定义的函数,它的作用是交换两个变量(a和b)的值。swap函数的形参p1、p2是指针变量。程序运行时,先执行main函数,输入a和b的值。然后将a和b的地址分别赋给指针变量pointer_1和pointer_2,使pointer_1指向a,pointer_2指向b。

7  数组指针

一个变量有地址,一个数组包含若干个元素,每个元素在内存中都有地址。

复制代码
int a[10];

int *p = a;

p和&a[0]的地址是否相同?
相同

复制代码
在C语言当中数组的名称代表数组的首地址,如果取数组名称的地址,C语言认为就是取数组的首地址。

int array[10] = { 6, 8, 9, 1, 3,4 };//array[0]的值是6
int *p = &array[0];//p指向了数组的第一个元素的地址
int *p1 = array;//p1指向了数组的首地址.
//*p和*p1是一样的。
8  通过指针引用数组元素

如果指针变量p已指向数组中的一个元素,则p+1指向同一数组中的下一个元素。

如果p的初值为&a[0],则:

1)   p+i和a+i就是a[i]的地址,或者说它们指向a数组的第i个元素。

2)   *(p+i)或*(a+i)就是p+i或a+i所指向的数组元素,即a[i]。例如,*(p+5)或*(a+5)就是a[5]。

3)   指向数组的指针变量也可以带下标,如p[i]与*(p+i)等价。

根据以上叙述,引用一个数组元素可以用:

1)   下标法,即用a[i]形式访问数组元素。在前面介绍数组时都是采用这种方法。

2)   指针法,即采用*(a+i)或*(p+i)形式,用间接访问的方法来访问数组元素,其中a是数组名,p是指向数组的指针变量,其处值p=a。

例:输出数组中的全部元素。(下标法)

main(){
  int a[10],i;
  for(i=0;i<10;i++)
    a[i]=i;
  for(i=0;i<5;i++)
    printf("a[%d]=%d\n",i,a[i]);
}

输出数组中的全部元素。(通过数组名计算元素的地址,找出元素的值)

main(){
  int a[10],i;
  for(i=0;i<10;i++)
    *(a+i)=i;
  for(i=0;i<10;i++)
    printf("a[%d]=%d\n",i,*(a+i));
}

输出数组中的全部元素。(用指针变量指向元素)

main(){
  int a[10],I,*p;
  p=a;
  for(i=0;i<10;i++)
    *(p+i)=i;
  for(i=0;i<10;i++)
    printf("a[%d]=%d\n",i,*(p+i));
}

main(){
  int a[10],i,*p=a;
  for(i=0;i<10;){
    *p=i;
    printf("a[%d]=%d\n",i++,*p++);
  }
}

注意:

1)   指针变量可以实现本身的值的改变。如p++是合法的;而a++是错误的。因为a是数组名,它是数组的首地址,是常量。


[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 3
支持
分享
最新回复 (7)
雪    币: 47147
活跃值: (20460)
能力值: (RANK:350 )
在线值:
发帖
回帖
粉丝
2
感谢分享,你己转正了。
2015-12-30 21:43
0
雪    币: 191
活跃值: (848)
能力值: ( LV12,RANK:530 )
在线值:
发帖
回帖
粉丝
3
感谢分享
2015-12-30 22:37
0
雪    币: 341
活跃值: (143)
能力值: ( LV7,RANK:110 )
在线值:
发帖
回帖
粉丝
4
萌萌哒的头像啊。。。。
2015-12-30 23:43
0
雪    币: 986
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
很不错的教程啊
2015-12-31 10:09
0
雪    币: 269
活跃值: (906)
能力值: ( LV12,RANK:345 )
在线值:
发帖
回帖
粉丝
6
坛主真是用心良苦。。。
2015-12-31 10:17
0
雪    币: 970
活跃值: (1264)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
看到c语言的精华 就赶紧过来围观 读完之后理解更深刻了 感谢分享
2015-12-31 10:54
0
雪    币: 112
活跃值: (293)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
我是来看头像的
2015-12-31 11:26
0
游客
登录 | 注册 方可回帖
返回
//