美文网首页C语言iOS技术文章
C语言指针基础☀️

C语言指针基础☀️

作者: LeaderBiao | 来源:发表于2016-06-22 11:36 被阅读194次
    • 版权声明:本文为博主原创文章,未经博主允许不得转载。

    C语言指针
    前导程序

    #include<stdio.h> 
    
    void change(int *);
    
    int main()
    {
      int a=90;
    
      change(&a);
    
      printf("a=%d\n",a);
    
      return 0;
    }
    
     
    void change(int *n)
    {
      *n=10;
    }```
    
    
    
    
    ####一、基本知识点
    

    int a=10;

    int *p;//定义一个int类型的指针

    p=&a;//指针变量p指向了变量a

    *p=20;//使用指针不通过变量直接修改变量a的值为20

    //*p表示访问指针变量p指向的存储空间```

    指针一个作用:能够根据一个地址值,访问(取值 | 赋值)对应的存储空间

    • 指针变量p前面的int,表示指针的类型

    ①. int *p;

    ②. *p=10;

    两个的区别:前一个起标识作用,表明定义的p是一个指针,后者的表示通过访问p指向的地址空间**

    二、指针使用注意

    ①. int *p;

    double d=10.0;

    p=&d;//不建议此种做法

    ②. int *p;

    p=200;//指针变量只能存储地址

    ③. int *p;

    printf(“%d\n”,*p);//指针变量未经初始化,不要拿来间接访问其他的存储空间

    ④. Int p=&a;但是不能写成 int p;p=&a;这种写法没有任何的意义,可以认为是和类型符一起使用的。

    ⑤. *是指针运算符,访问指针指向的空间

    三、指向指针的指针

    int a=10;
    
    int *p=&a;//指向int型的指针
    
    int **p1=&p;//指向指针的指针
    
    int ***p2=&p1;//三级指针```
    
    ![](https://img.haomeiwen.com/i838345/21631b7190b9e164.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
    
    >*p2相当于访问p1;
    
    >**p2相当于访问p;
    
    >***p2相当于访问a;
    
    >*p1相当于访问p;
    
    >一颗星一条线。
    
    
    ####四、指针练习
    
    - 编写一个函数,计算a和b的和与差(一个函数返回两个值)
    提示:指针的作用之一:实现让函数拥有多个返回值
    
    

    include<stdio.h>

    int SumAndMinus(int n1,int n2,int *n3)
    {
    *n3=n1-n2;

    return n1+n2;
    }

    int main()
    {
    int a=10;

    int b=11;

    int sum;

    int minus;

    sum=SumAndMinus(a,b,&minus);

    printf("和=%d,差=%d\n",sum,minus);
    }```

    五、有关指针的疑问

    注意:任何类型的指针都占据8个字节的存储空间,那么为什么还要为指针加上类型呢?

    对下面一段代码进行内存分析,可以证明指针类型不正确带来的严重后果。

    int i=2;
    
    char c=1;
    
    int *p=&c;//本应该是char类型的,写成了int类型
    
    printf(“c的值是%d\n”,*p);//打印结果为513,而非1
    
    printf(“c的值是%d\n”,c);//值为1```
    
    - 下面是上述代码的结果的内存分析:
    ![](https://img.haomeiwen.com/i838345/cd027f119b93c111.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
    
    - **指针p访问的本应该是1个字节空间的数据,此时因为指针的类型是int型的,因此程序自然的从指向的地址0x0a开始读取了4个字节的数据,访问的数据从1变成了513。**
    
    >提示:明确了指针的数据类型,指针才能够正确的访问应该访问的空间数据。
    
    ####六、指针和数组
    
    

    int ages[5]={10,9,8,7,6};

    //遍历数组

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

    printf(“%d\n”,ages[i]);

    //使用指针遍历数组

    int *p;

    p=ages;//也可以写成p=&ages[0];,指针变量p指向了数组的首元素```

    • 元素的地址:
    第一个元素的地址p    &ages[0]
    
    第二个元素的地址p+1    &ages[1]
    
    第三个元素的地址p+2    &ages[2]
    
    元素的值
    
    *p        ages[0]
    
    *(p+1) ages[1]
    
    *(p+2) ages[2]
    
    把指针当做数组来用:
    
    for(int i=0;i<5;i++)
    
    printf(“%d\n”,*(p+i));```
    
     
    ######(1)数组元素的三种访问形式:
    
    >①. 数组名[下标]
    
    >②. 指针变量名[下标]
    
    >③. *(p+1)
    
    ######(2)指针变量的+1究竟是加多少?这取决于指针的类型,如果是char类型则加1个字节,如果是int类型的,则加4个字节。
    
    ######(3)利用指针来接收一个数组,指针变量指向了数组的首元素。
    

    Void change(int array[])等价于void change(int *array)。```

    前者存储的虽然是数组元素的首地址,但是在传递时就已经变成指针了。

    示例:

    void change(int *array)
    {
      //printf(“%d\n”,array[2]);
    
      printf(“%d\n”,*(array+2));
    }
    
    int main()
    {
      int ages[5]={1,2,3,4,5};
    
      change(ages);
    }```
    
    >调用的结果为:数组的第三个元素3
    
    - *若改给change(&ages[2]);则调用的结果为5,因为此时array指向的是ages[2],把ages[2]当做了array的首元素.*
    
    
    ####七、指针和字符串
    
    ######(一)基础知识
    
    >下面两行代码有着本质的区别:
    
    

    ①. char name[]=“it”;

    ②. char *name2=“it”;//指针变量name2指向了字符串的首字符i```

    char name[0]=‘y’;//改变第一个元素的值
    
    printf(“%s\n”,name);//打印结果为yt
    
     
    *name2=‘y’;
    
    printf(“%s\n”,name2);//此时程序崩溃```
    
    - 这是因为,两者一个是字符串变量,一个是字符串常量。C语言的数组元素存放于栈,里面的元素可以随便修改,称为字符串变量。而字符串常量存放于常量区,会缓存起来是不可更改的。
    
    

    char *name1=“it”;

    char *name2=“it”;

    printf(“%p %p”,name1,name2);//地址是一样的,说明name1和name2指向的是同一个字符串。```

    掌握字符串定义的两种方式:

    • ①. 利用数组

    特点:字符串里边的字符是可以修改的,适用于内容需要经常修改时。

    • ②. 利用指针

    特点:其实是一个常量字符串,里面的字符不能修改,适用于字符串的内容不需要修改,且这个字符串经常被使用时。

    (二)指针数组
    • 整型数组:这个数组中存放的都是整型数组

    • 指针数组:这个数组中存放的都是指针

    int ages[5];
    
    char *name[5]={“jack”,“rose”,“yang”};//字符串数组的常见写法```
    
    **对应于:**
    
    

    char name2[3][10]={“jack”,“rose”,“yang”};```

    保存字符串数组的两种方式:

    • ①. 指针数组(字符串数组)

    • ②. 二维字符数组(字符串数组)

    如何输入字符串?(使用数组——因其可变)

    int main()
    {
      char name[20];
    
      printf(“请输入姓名:\n”);
    
      scanf(“%s”,name);
    
      printf(“%s”,name);
    }```
    
    
    ####八、返回指针的函数
    
    **程序示例:**
    
    
    

    include<stdio.h>

    char *test();

    int main()
    {
    char *name=test();

    printf(“name=%s\n”,name);

    return 0;
    }

    char *test() //返回指针的函数
    {
    return “rose”;
    }```

    九、指向函数的指针

    数组名即数组的地址,函数名即函数的地址。

    • 假设有函数:
    void Test ()
    {
      printf(“调用了test函数\n”);
    }
    
    void (*p)();  //void指针变量指向的函数没有返回值,()表示p指向的函数没有形参
    
    p=test; //有指针p,把指针p指向函数```
    
    ***有三种方式可以操纵函数:***
    
    
    >①. 直接调用test();
    
    >②. 利用指针变量简介调用  (*p)();
    
    >③. 简化使用p()
    
    
    **练习:**
    

    假设有函数声明为 int sum(int a,int b)

    则相对应的指向该函数的指针应该定义为:int (*p)(int ,int);

    把指针变量p指向函数:p=sum;

    调用该函数的三种方式:

    (1)int c=p(10,12);

    (2)int c=sum(10,12);

    (3)int c=(*p)(10,12);

    假设函数声明为:double haha(double a,char *b,int c);

    则定义一个指向haha函数的指针应该为:double (*p)(double,char *,int)=haha;

    相关文章

      网友评论

      本文标题:C语言指针基础☀️

      本文链接:https://www.haomeiwen.com/subject/evtndttx.html