iOS基础(c)—指针

原创 2015年07月09日 23:44:11


------ 知之博客 期待与您交流! -------


一 指针的概念

    内存单元的编号也叫做地址。既然根据内存单元的编号可以找到所需的内存单元,所以你通常也把这个地址称为指针。

 

二 指针存在的价值

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

2).让函数有多个返回值;

3).可以改善某些程序的效率;

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

 

三 指针变量

    c语言中,允许用一个变量存放指针,这种变量称为指针变量。因此,一个指针变量的值就是某个内存单元的地址或称为某个内存单元的指针。

    注:指针是地址,是一个常量;指针变量是存放一个地址,是一个变量。

 

四 指针变量的定义

1).指针类型说明,即定义变量为一个指针变量;

2).指针变量名

3).变量值(指针)

    一般形式:

    类型说明符  *变量名;

    例如:  int  * p ;  //一个指向整型变量的指针

                 long * p ; //一个指向长整型变量的指针

                 float * p ; //一个指向浮点型变量的指针

    *  表示定义了一个指针变量

    一个类型的指针只能指向同类型的变量,不能指向其他类型的变量

    指针也可以被声明为全局 、静态局部和局部的。

    如果一个指针变量定义以后,如果不进行初始化,这个指针变量存放的是一个垃圾数,这个指针变量称为野指针

 

五 指针的应用场景

    1)在被调函数中可以修改主调函数中的变量的值

    2)让函数有多个返回值

 例如:

#include <stdio.h>

void yunsuan(int x,int y,int *he,int *cha) {
    
    *he = x + y;<span style="white-space:pre">	</span>//计算两个数的和
    *cha = x - y;<span style="white-space:pre">	</span>//计算两个数的差
    
}

int main(int argc, const char * argv[]) {
   
    int he = 0,cha = 0;
    yunsuan(2, 3, &he,&cha);
    printf("he = %d\ncha = %d\n",he,cha);
    return 0;
}

    例子中函数yun suan并没有返回值,却借助指针修改了指针指向的内存空间的数值,可以看作是无形之中添加了返回值。

    二级指针以及多级指针在iOS开发中运用较少,简单的介绍一下。

    二级指针:如果一个指针变量存放的又是另一个指针变量的地址,则称这个指针变量为指向指针的指针变量,也成为“二级指针”。多级指针以此类推。接下来用一个图简单了介绍一下二级指针和一级指针的区别。


 

六 指针的类型

    简单地讲,只要把指针声明语句里的指针名字去掉,剩下的部分就是这个指针的类型。这是指针本身所具有的类型。

    例如:

(1) int * p ;                         //指针的类型是 int*
(2)char*p;                            //指针的类型是 char*
(3)int**p;                            //指针的类型是 int**
(4)int(*p)[3];                        //指针的类型是int(*)[3]
(5)int*(*p)[4];                       //指针的类型是int*(*)
 

七 指针指向的类型

    当通过指针来访问指针所指向的内存区时,指针所指向的类型决定了编译器将把那片内存区里的内容当做什么来看待。从语法上看,你只须把指针声明语句中的指针名字和名字左边的指针声明符*去掉,剩下的就是指针所指向的类型

    例如:

(1)int*p;
               //指针所指向的内容是int
(2)char*p;
              //指针所指向的内容是char
(3)int**p;              //指针所指向的内容是int*

(4)int(*p)[3]; <span style="white-space:pre">		</span>//指针所指向的的类型是int()[3]
(5)int*(*p)[4];<span style="white-space:pre">		</span>//指针所指向的的类型是int*()[4]

    指针本身占了多大的内存?你只要用函数sizeof(指针的类型)测一下就知道了。在 32 位平台里,指针本身占据了 4个字节的长度。

 

八 指针的算术运算

    指针可以加上或减去一个整数。指针的这种运算的意义和通常的数值的加减运算的意义是不一样的,以单元为单位。

    例如:

char a[10];                 //定义一个char类型的一维数组
int *p = (int*)a;           //定义一个指向整型变量的指针p,强制转换并不会改变a的类型
p++;                <span style="white-space:pre">	</span>    //指针指向下一个单元

     指针 p 的类型是 int*,它指向的类型是 int,它被初始化为指向整型变量 a。第 3 句中,指针 p 被加了 1,编译器处理的方式:将指针 p 的值加上sizeof(int),在 32 位程序中,是被加上了4,因为在 32 位程序中,int 占 4 个字节。由于地址是用字节做单位的, 故 p 所指向的地址由原来的变量 a 的地址向高地址方向增加了 4 个字节。由于 char 类型的长度是一个字节,所以,原来 p 是指向数组 a 的第 0 号单元开始的四个字节,此时指向了数组 a 中从第 4 号单元开始的四个字节。

    注意两个指针不能进行加法运算,属于非法操作,因为进行加法后,得到的 结果指向一个不知所向的地方,并且没有实际意义。但是两个指针可以进行减法操作,但必须类型相同,一般用在数组方面

 

九 指针与数组

    说到数组的概念如果不理解的话,可以参阅我的文章《黑马程序员-iOS基础(c)-数组》。首先来看一个例子:

例如:

int array[5]={0,1,2,3,4,},value; 
... 
... 
value = array[0];                   //也可写成:value=*array; 
value = array[3];                   //也可写成:value=*(array+3); 
value = array[4];                   //也可写成:value=*(array+4); 


    由此可见,数组名array代表数组本身,类型是int [5]。但如果把array看做指针的话,它指向数组的第0个单元,类型是int *,所指向的类型是数组单元的类型即int。因此*array等于0就一点也不奇怪了。同理,array+3是一个指向数组第3个单元的指针,所以*(array+3)等于3。其它依此类推。因此数组的数组名可以看作一个指针

    sizeof(指针名称)测出的是指针自身类型的大小呢还是指针所指向的类型的大小?来看一个例子。

例如:

int (*p)[10]; 
 
则在32位程序中,有:  
sizeof(int(*)[10])== 4 
sizeof(int[10]) == 40 
sizeof(p) == 4 

    可以看出sizeof(对象)测出的都是对象自身的类型的大小,而不是别的什么类型的大小

 

十 指针和结构体

首先来定义一个结构体:

例如:

structMyStruct
       {
         int a;
         int b;
         int c;
};

struct MyStruct ss={20,30,40};          //声明了结构对象 ss,并把 ss 的成员初始化为 20,30和40。
struct MyStruct *ptr=&ss;               //声明了一个指向结构对象ss 的指针。它的类型是 MyStruct *,它指向的类型是 MyStruct。
int *pstr=(int*)&ss;                    //声明了一个指向结构对象ss 的指针。但是 pstr 和 //它被指向的类型 ptr 是不同的。

怎样通过指针 ptr 来访问 ss 的三个成员变量?

答案:

ptr->a;                       //指向运算符,或者可以这们(*ptr).a,建议使用前者
ptr->b;
ptr->c;

怎样通过指针 pstr 来访问 ss 的三个成员变量?

答案:

*pstr;                         //访问了 ss 的成员 a。
*(pstr+1);                 //访问了 ss 的成员 b。
*(pstr+2)                  //访问了 ss 的成员 c。

    以上例子中,即使*pstr 访问到了结构对象 ss 的第一个成员变量a,也不能保证*(pstr+1)就一定能访问到结构成员b。因为成员 a 和成员 b 之间可能会有若干填充字节,说不定*(pstr+1)就正好访问到了这些填充字节。这也间接地证明了指针的灵活性。


十一 指针和函数

对于函数的了解可以查看我的文章《黑马培训-iOS基础(c)-函数》,文章对函数做了详细的介绍。还是首先来看一个例子:

例如:

int fun(char*);
int a;
charstr[]="abcdefghijklmn";
a=fun(str);
int fun(char*s) {
    int num=0;
    for(int i=0;;) {
num+=*s;
s++;
       }
return num;
}

    本例中的函数 fun 统计一个字符串中各个字符的 ASCII 码值之和。数组的名字也是一个指针。在函数调用中,当把 str 作为实参传递给形参 s 后,实际是把 str 的值传递给了 s,s 所指向的地址,就和 str 所指向的地址一致,但是 str 和 s 各自占用各自的存储空间。在函数体内对s进行自加1运算,并不意味着同时对str进行了自加1运算。

    总结:可以把一个指针声明成为一个指向函数的指针,也可以把指针作为函数的形参。在函数调用语句中,可以用指针表达式来作为实参

    

    在使用指针时,程序员心里必须非 常清楚:我的指针究竟指向了哪里。在用指针访问数组的时候,也要注意不要超出数组的低端和高端界限,否则也会造成类似的错误。

 


版权声明:本文为博主原创文章,未经博主允许不得转载。

C语言「指针、链表」入门心得

小白的日常学习——指针、链表。学的很浅,欢迎吐槽。
  • Zhangyucha0
  • Zhangyucha0
  • 2016年05月10日 15:52
  • 724

C语言基础知识之(十三):指针、指针和数组

一、指针的声明和定义 1、访问数据一般有两种方式:直接、间接 直接:通过变量访问数据, 如:通过变量a访问内存单元。 int a = 10; printf("%d\n",a); 间接:通...
  • leleyuan1130
  • leleyuan1130
  • 2015年08月30日 20:12
  • 241

Object-C基础(5)——指针

要接受的观点     1.操作系统管理内存分配(有人来了,要分房间给它住)、内存回收(人走了,房间要收回来)的方式就是给内存编号。这个编号是二进制的编号,而且与操作系统位数相关。     2.  所有...
  • panjican
  • panjican
  • 2016年03月27日 11:43
  • 1013

C语言回顾(七、多重指针,argc,argv,动态内存分配,void指针,const)——iOS开发基础

整理C语言知识点(不是细节,知识个人觉得较重要或易忘的)。 多重指针,argc,argv 动态内存分配:malloc,calloc,realloc,free。void指针类型。 const与指针变量...
  • Zsk_Zane
  • Zsk_Zane
  • 2015年06月22日 17:27
  • 1448

C语言-------------指针小程序的练习

1、猜数:首先生成一个介于1-100之间的整数,从键盘不断输入数值直到该数值与生成的那个数相符为止,并打印出猜数的次数#include #include void creat(int *secr...
  • zyx6a
  • zyx6a
  • 2013年04月03日 21:34
  • 1181

c语言基本类型和指针

//导入标准函数库(类似于java的导包) #include //导入标准函数库(system、sizeof等等......) #include //windows系统的api #include ...
  • chuyouyinghe
  • chuyouyinghe
  • 2016年10月13日 10:37
  • 501

【IOS 开发学习总结-OC-7.7-★★】 objective-c——指针

指针是 C 语言的一个重要概念。OC 系统类型的变量,自定义类型的变量都是指针。指针的概念定义一个变量后,程序运行过程中,该变量保存在内存中,那要使用该变量的值有这样2种方法: 1.通过变量来访问它...
  • senwin2009
  • senwin2009
  • 2015年09月14日 15:08
  • 1553

指针基础概念

第一节;简述指针的一些概念 都是在C的语言基础上的;本人开始细学指针,所以有错误或不严谨的地方请大家多多指出。 刚开始可能会有的晕,但详细介绍的; 一;关于地址的一些概念1。内存单元;在计算机中...
  • zw1996
  • zw1996
  • 2016年05月05日 17:12
  • 245

objc直接通过指针访问对象实例变量

我们现在来做一件被认为是very bad的事情,如题所示;无论实例变量是私有的、保护的都可以通过地址访问到,并且还可以修改之。这可以称之为所谓的“超级键值编码”。首先上代码:#import @inte...
  • mydo
  • mydo
  • 2015年06月30日 17:29
  • 1016

c语言函数指针学习心得

1.指针函数的定义     顾名思义,指针函数即返回指针的函数。其一般定义形式如下:       类型名*函数名(函数参数表列);     其中,后缀运算符括号“()”表示这是一个函数,其前缀运...
  • huang_jinjin
  • huang_jinjin
  • 2012年03月20日 20:27
  • 4195
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:iOS基础(c)—指针
举报原因:
原因补充:

(最多只允许输入30个字)