码迷,mamicode.com
首页 > 其他好文 > 详细

指针-笔记

时间:2015-07-03 06:55:08      阅读:133      评论:0      收藏:0      [点我收藏+]

标签:

什么是指针?

  指针是一类数据类型的统称.

  这种类型的数据用来专门存储内存中的一块空间的编号,用于表示这一段内存.以实现通过内存地址(编号)完成各种运算.也就是一个指针指向一块内存空间,指针把这一块空间的第一个Byte的空间的地址存在指针的右值中.指针自己也是有内存空间和内存地址的.

   数祖名也是个指针,而且是个常量指针. 该指针指向数组在内存中的那块空间,并把数组第一个字节的地址存在指针的右值中.该地址和数组第一个元素的首地址相同. 指针的类型有很多,其他在下面体现,这里就不一一举例了.

常见的两种和指针有关的操作符:

  #1 * 定义指针的时候相当于类型说明符,说明接下来定义的变量是指针类型; 在使用指针变量时 *p 代表把指针变量p指向的内存空间的值去除;

  int a, *p, p = a; *p = 5;

  在定义一个指针时 int * p中的 *  并不是算术运算符乘, 像这样一词多义的情况,在C语言中还有很多. 在这里 * 是指针类型说明符, 说明p是一个指针, 这里的int 代表指针p指向的内存空间存放的数据是int 类型的.*p = 5, 这里的 * 又是另一个意思, 是一个间接引用运算符.它代表取出指针指向的空间, 在这里是把int类型数据5拷贝到指针p指向的内存空间中, 也就是把变量a的右值改成5.

  #2 & 取指针运算符

  之前学习scanf(“%d”, &a)函数时常用的”&”符号,其实就是求指针运算符,取得一个指针指向变量a的空间,&a把a的空间的手地址存放在&a的右值中.通过这个指针可以找到a的地址,从而把接受到的数据按照%d的格式存放在a的空间.

指针的优点:

  a.为函数提供修改调用变量的灵活手段;

  b.让函数有多个返回值

  c.可以改善某些子程序的效率

  在数据传递时,如果数据块较大(比如说数据缓冲区或比较大的结构),这时就可以使用指针 传递地址而不是实际数据,即提高传输速度,又节省大量内存。

  d.为动态数据结构(如二叉树、链表)提供支持

二级指针

  如果一个指针指向另一个指针,则称这个指针为二级指针. 二级指针的右值存放的是一级指针的地址. 

  定义指针时, 变量名前有几个*就是几级指针.

  <其他待补充...>

一维数组指针

  即指向一维数组的指针.

  int a[5] = {1, 2, 3, 4, 5}; int *p =a;

  指针变量p指向数组a的空间,a的首地址作为值存放在p的右值中.这是指针变量p可以代替数祖名使用,例如p[0], 相当于a[0].但由于p是变量,所以可以使用++ -- 等运算,但是数组名是常量,则不可以这样运算.

二维数组指针

  指向二维数组的指针.内容存放的是数组的行首地址.

  int arr[3][5]; int (*p)[5] = arr;

  二维数组指针是单个的变量. p + 1, 代表第二行的指针.

*注意: #1 *p左右的括号不可少, 如果少了括号则变成二维指针数组

     #2 指定列宽[5]不可少, 这是要告诉编译器该数组指针指向的数组结构,其列宽是5.

一维指针数组

  即:数组的内容存放的是指针变量

  int a, b, c;

  int *p[3] = {&a, &b, &c};

指针之间的运算

  当两个指针指向同一个数组, 两个指针想减的结果说明两个指针相隔了几个元素.p1 - p2 > 0 说明p1在高地址位, 相反则在低地址位. p1 - p2 == 0则说明两个指针指向了同一个元素.

  两指针之间只有减法运算有意义,其他运算是没有意义的.

数祖名访问二维数组的每个元素

  如前面所说,数组名也是个指针,所以通过数组名也可以访问数组中的每个成员.

  int a[3][5];

  a + i : 可以代表行的首地址, 也就是行指针

  a[0] + j :  a[0] + j可以代表列指针

  (*(a + i) + j) : 可以代表任意一个元素的地址,所以

  *(*(a + i) + j): 可以取出任意一个元素的值

 

字符串指针

  指向字符串的指针.

1. 定义方法:char *变量名 = ”字符串内容“;// “字符串内容”是常量,保存在内存中的常量区

作用:用来保存一个字符串,保存了字符串的首地址

2. 字符串指针不能从键盘接收一个字符串,但是可以通过malloc()先申请一定长度的内存空间,用来接收键盘输入的字符串。

现在可以保存字符串的几种方式;

#1 字符数组

  把字符串通过数组保存到栈中,内容是可读可写的,也就是说可以改变字符数组的内容

#2 二维字符串数组

#3 字符串指针:

  指向字符串常量的首地址,字符串常量是只读的,不可以更改其内容。但是字符串指针可以重新指向其他字符串地址。

#4 char类型指针数组

  char *p[3] = {"Hello", "ZJL", "Hello"};

  数组每个元素都指向一个字符串.

 

指针函数

  返回值为指针的函数称为指针函数.

定义:

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

    函数体;

  }

函数名前加*说明返回的是指针,类型说明符说明返回的指针指向的空间内元素的类型.

函数指针

 

  一个函数总是占用一段连续的内存空间,函数名就是该函数空间的首地址.我们把这种指向函数的指针变量称为”函数指针”;

 

 函数指针变量的定义:

 

  返回值类型 (*变量名)(函数的参数);//可以省略形参名,但不能省略形参类型

 

 注意:

 

1)函数指针变量不能进行算术运算,这是与数组指针变量不同的。数组指针变量加减一个整数可 使指针移动指向后面或前面的数组元素,而函数指针的移动是毫无意义的。

 

2)函数调用中"(*指针变量名)"的两边的括号不可少,其中的*不应该理解为求值运算,在此处它 只是一种表示符号 

 

野指针

  定义指针时,没有初始化该指针. 又或者指针指向目标丢失(例如malloc等函数生成的内存空间被free后),这样的指针叫野指针.

 

  定义指针变量的同时如果没有指向一个确定的目标,最好初始化为NULL,用完指针后也将指针变量设置为NULL.

 

 内存泄漏:

 

  int *p = (int *)malloc(16);p在棧中, malloc(16)在堆中

 

解决方法:p释放前,先释放堆中的malloc(16)申请的空间

 

free函数使用:先导入库文件

 

  free(p);//p要释放的空间的首地址,free代表p指向的那块空间可以被重新利用

 

  p = NULL;//把释放空间后的指针指向NULL,避免p还指向之前的内存空间

 

1. 常见的内存分配的函数

malloc calloc realloc 在堆中分配空间

###malloc

  void *malloc(unsigned size),包含在库函数sodlib.h中,作用是在内存的队区分配一个大小为size连续的内存空间,如果分配成功,函数返回新分配内存的首地址,否则,返回NULL.注意:鉴于上述这点,一般在写程序需要判断分配内存是否成功

注意:

  malloc申请的空间,如果该空间不初始化(赋值),则空间内容是不确定的.

  memset(p, ‘A’, 16);这个函数可以给malloc申请的空间初始化,内容全部为’A’,其中p为接收malloc申请空间的指针,16为空间大小.

 ###calloc

  clloc(块数,每块的长度),分配指定块数的连续的内存空间.分配成功则返回空间首地址,否则返回NULL.

注意:

  calloc分配内存空间成功后,会自动初始化分配的内存空间,初始化为0.

 ###realloc

  realloc可以给已经存在的空间重新分配大小,但地址可能会改变.之前空间的数据不会丢失,会被拷贝到新的空间.所以在使用该函数时,需要把返回值重新赋值给之前的指针.

 

指针-笔记

标签:

原文地址:http://www.cnblogs.com/siyingcheng/p/4617572.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!