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

最最最最最最最最基础的C---其他数据类型:指针

时间:2015-11-19 07:24:55      阅读:179      评论:0      收藏:0      [点我收藏+]

标签:c语言

了解指针之前先了解一些知识:

变量有关概念:     存储内容<==>数据值

                  空间大小<==>数据类型

                  空间位置<==>地址

                  生存周期<==>存储类别

变量的地址:系统为变量分配的内存单元的地址(无符号整型数)

 

变量的访问:直接访问:按变量地址存取变量值的方式

            间接访问:通过访问一个指向你所要访问的变量的地址的变量,再去访问


指针

定义:为了方便访问内存中的内容,给每一个内存单元(字节)一个编号,这个编号,称为地址,也就是指针(指针就是内存地址,一个变量所在的内存地址就是该变量的指针)

 

指针是一种数据类型

 

指针常量:通过&来表示: &变量名

指针变量:存储地址的变量

          为了表示指针变量与它所指向的变量之间的联系,用“*”符号表示“指向”

指针变量定义:基类型 * 指针变量名

指针变量的赋值(初始化):

             0.直接赋值NULL或者0

             1.相同类型变量的地址

             2.相同类型的指针变量

指针运算符:&:取地址运算符,取变量内存地址,即取指针。

            *:解析引用符(指针运算符),取内容,取内存地址对应的变量,即取指针所指的变量。

通过变量去访问数据:直接访问

通过地址去访问数据:间接访问

 

int a=3;//定义变量a

int *p; //定义指针变量p

p=&a;   //给指针变量赋值,把a的地址赋值给p

int *p1=&a;// 或者直接在定义时赋值

 

任意类型的指针内存大小都是为4个字节

    cout<<sizeof(int*)<<endl;

void 型指针可以指向任意类型


指针与算术运算符(指针的偏移)

指针+(-)整数:指针的偏移

p+1:1表示的含义:1个单位=sizeof(指针指向的类型)

p++等价于p=p+1,p--等价于p=p-1

举例说明:

intmain(intargc, char **argv)

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

        int *p1 = (int *)(a+1);

        int *p2 = (int *)(&a+1);

        cout<<*(p1-1)<<endl;

        cout<<*(p2-1)<<endl;

        return 0;

}

*(a+1)就是a[1],*(ptr-1)就是a[4],执行结果是1,5

&a+1不是首地址+1,系统会认为加一个a数组的偏移,是偏移了一个数组的大小(本例是5个int)

int *ptr=(int *)(&a+1);

则ptr实际是&(a[5]),也就是a+5

原因如下:

     &a是数组指针,其类型为 int (*)[5];

     而指针加1要根据指针类型加上一定的值,

     不同类型的指针+1之后增加的大小不同

     a是长度为5的int数组指针,所以要加 5*sizeof(int)

     所以ptr实际是a[5]

     但是prt与(&a+1)类型是不一样的(这点很重要)

     所以prt-1只会减去sizeof(int*)

     a,&a的地址是一样的,但意思不一样,a是数组首地址,也就是a[0]的地址,&a是对象(数组)首地址,a+1是数组下一元素的地址,即a[1],&a+1是下一个对象的地址,即a[5].


指针与数组

C规定:数组名代表数组中的首地址

C规定:如果指针变量p已指向数组的一个元素,则p+1指向同一数组中的下一个元素,并不是将p的值(地址)简单加1。(移动一个数组元素所占的字节数)

指针与一维数组:(指针变量的赋值3.相同类型的一维数组名给指针变量赋值

 

int a[5]={2,5,3,6,8};//定义数组变量a

int *p; //定义指针变量p

p=&a;   //给指针变量赋值,把a的首地址赋值给p

或者在定义时赋值:

int *p=&a[0];

 

for(int i=0;i<5;i++)

    cout<<p[i]<<endl;//指针与下标的形式操作数组

 

指针访问数组元素:

数组元素都是连续存放的,数组变量本身保存了第一个数组元素的地址,系统可以快速定位各元素所在内存,从而快速访问数组元素。

元素地址=首地址 + 数组元素类型占用字节数 *索引

指针变量加减n时,代表将该指针的地址加减n*变量字节大小。

如果arr是数组,arr+1代表索引为1的元素地址,arr存放索引为0的元素地址, arr+1与 &arr[1]等价

如果arr是数组,*(arr+1)取索引为1的元素值,即*(&arr[1])。*(arr +1)与arr[1]等价

当两个指针变量指向同一个数组时:

两个指针变量可以比较,指向前面元素的指针小于指向后面元素的指针;

两个指针变量可以相减,返回两个指针所指数组之间元素的个数。


指针与二维数组

   专门的类型  数组指针:指针指向多维数组(数组名赋值)

   intn[3][4]={

         {1, 3, 5, 7},

         {2, 4, 6, 8},

         {9,10,11,12}

    };

   int*p= &n[0][0];

   for(inti=0;i<12;i++)

    {

         cout<<*(p+i)<<endl;     //三者含义相同,均表示输出第几个元素

         cout<<*(n[0]+i)<<endl;

         cout<<*(&n[0][0]+i)<<endl;

    }

    cout<<sizeof(p)<<endl;

    cout<<sizeof(&n[0][0])<<endl;

    cout<<sizeof(n[0])<<endl;//求数组的大小(二维数组第一行)

    下面四个值一样,但是含义不一样.

    cout<<*n<<endl;        //n[0]

    cout<<*&n[0]<<endl;    //n[0]

    cout<<*n[0]<<endl;     //n[0][0]

    cout<<*&n[0][0]<<endl; //n[0][0]

 

    定义一个数组指针pn:指向列数为4的二维数组

    int (*pn)[4]=n;

    定义一个指针数组:数组中每一个元素都是int指针

    int *ppn [3]={n[0],n[1],n[2]};

    定义一个二级指针:指针变量中保存另一个指针变量的地址

    int **pp=ppn; //ppn数组名等于&ppn{0]

 

     //cout<<*(*(pn+2)-2)<<endl;//6

    //cout<<*(*pn+2)-2<<endl;//3

    //cout<<*(pn[2]+1)<<endl;//10

    //cout<<*(*(ppn+1)-2)<<endl;//5

    //cout<<*(*(pp+2)+2)<<endl;//11

    //cout<<*(pp+1)[0]<<endl;//2  n[1][0]

    //cout<<(*(pp+1))[1]<<endl;//4//n[1][1]


二级指针:指针的指针

指针变量也是变量,也有自己的存储地址,如果再次定义变量来保存指针变量的存储地址,这个地址就是指向指针变量的指针。

语法:类型** 变量名;

voidzhizhentest4_2(){

inta = 5;

int*p = &a;

int**pt = &p;

printf("%p\n",p);

printf("%p\n",pt);

printf("%d\n",**pt);

}

输出:

0012FEB4

0012FEB0

5

指针变量p保存的是a的地址0012FEB4

指针变量pt保存的是p的地址0012FEB0,而p本身保存的是指针,所以pt保存的是指向指针变量p的指针(内存地址)

*pt表示获取pt所指向的变量p,而p本身也只指针变量,保存的是a的地址,所以还需要再加一个*来取p所指的


指针与字符串:数组与字符串

(指针变量的赋值)  4.字符串可以给指针变量赋值

定义一个数组c用字符串初始化:把字符串中的每一个字符赋值给每一个元素

char c[10]="abcd";

c[10]="abcd";//错误,c[10]:数组的第11个元素,数组越界。数组元素(char)不能用字符串赋值

c="abcd";//错误,c数组名,首地址指针.常量

char c1[10]="abcd";

定义一个指针p用字符串初始化:把字符串的首地址赋值给指针

char *p="abcd";//字符串有自己独立的内存

      p="abcd";//正确

char *p1="abcd";

cout<<p<<endl;

查看字符串的首地址

cout<<(int *)p<<endl;

cout<<(c==c1)<<endl;//输出0;两个数组的首地址肯定不一样

cout<<(p==p1)<<endl;//输出1;相同字符串同一段内存


指针与函数

函数的入口就是该函数的入口地址

可以通过一个指针指向函数,然后通过该指针变量来调用函数

函数指针定义:

      数据类型(*指针变量名)(函数参数表列)

给函数指针变量赋值,只需要给出函数名而不必给出参数

对函数指针,指针与运算符的运算无意义

 

返还指针值的函数(指针型函数)定义:

      类型名 * 函数名(参数表列)

指针与const

    const尽量理解为只读类型,不要理解为常量

      const int n=10; //符号常量:必须初始化,不能修改值(就是不能赋值)

             n=10; //错误;常量不能赋值

       intconst m=20; //const 也可以写在数据类型后面

        int *p5=&n;//错误

 

    常量指针:只读类型指针

    const int * p;

    int const * p1;

    p = &n;

    int n1=20;

      p=&n1;//常量指针可以改变指向(指向变量)

     *p=30;//错误,常量指针不能通过指针取修改变量的值 

 

    指针常量:指针本身是一个常量:必须初始化

    int * const p2=&n1;

    *p2=40;//可以通过指针常量修改变量的值

     p2=&n; //错误,指针常量不能改变指向

     int *const p3=&n;//错误,普通类型的指针变量不能指向常量(const类型的数据) 

                 

     指向常量的指针常量:只读类型的指针常量:既不能改变值,也不能改变指向

    const int *const p4=&n;


本文出自 “毕业---觉醒---行走” 博客,请务必保留此出处http://tjy888.blog.51cto.com/5576345/1714415

最最最最最最最最基础的C---其他数据类型:指针

标签:c语言

原文地址:http://tjy888.blog.51cto.com/5576345/1714415

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