今天学习了复杂数据类型中得指针,指针是关键中的关键

一、指针

1.基本使用

1>定义

#include <stdio.h>

void change(int);

int main(int argc, const char * argv[])
{

    /*
     int a = 90;
     
     change(&a); 
     
     printf("a = %d\n",a);
     */
    
    //指针的定义:
    //变量类型  变量名  
    //格式:变量类型 *变量名;  int *p
    //指针变量只能存储地址
    //指针就一个作用:能够根据一个地址值,访问对应的存储空间
    //指针变量p前面的int:指针变量p只能指向int类型的数据
    
    int *p;//这里的*只是定义这个指针
    
    int a = 90;
    
    //指针变量p指向了变量a
    p = &a;
    
    *p = 10;//这里的*是完成指向a地址的一个过程,即进入了a地址,修改a的值
    
    a = 20;
    printf("%d\n",*p);
    
    return 0;
}

void change(int n)
{
    n = 10;
}



2>配合定义作出的指针内存分析


ios14指针控制是什么意思 ios 指针_指针变量

2.利用指针修改a的值

//利用指针修改a的值

#include <stdio.h>

void change(int *n);

int main(int argc, const char * argv[])
{
    int a = 90;
    
    change(&a);
    
    printf("%d\n",a);
    
    return 0;
}

void change(int *n)
{
    *n = 10;
}



3.关于指针的使用注意事项

#include <stdio.h>

int main(int argc, const char * argv[])
{
    /*不建议的写法,int *p只能指向int类型的数据
     int *p;
     double d = 10.0;
     p = &d;
     */
    
    /*指针变量只能存储地址
     int *p;
     p = 200;
     */
    
    /*
     int *p;
     printf("%d\n",*p);
     */
    
    int a = 10;
    /*
     int a;
     a = 10;
     */
    
    /*
     int *p;
     p = &a;
     */
    
    
    //定义变量时的*仅仅是一个象征,没有其他特殊含义
    int *p;
    
    //不正确的写法
    //*p = &a;
    p = &a;
    
    //这个时候的*的作用:访问指向变量p指向的存储空间
    *p = 20;
    
    char c = 'Q';
    
    char *cp = &c;//其实就相当于(char *)cp = &c;
    
    *cp = 'D';
    
    printf("%c\n",c);
    
    return 0;
}



4.指向指针的指针

1>函数例子

#include <stdio.h>

int main(int argc, const char * argv[])
{

    int a = 10;
    
    int *p = &a;
    
    int **pp = &p;
    
    //a = 20;
    
    //*p = 20;
    
    /*
     (*pp) == p;//这里pp储存的是p的地址,*pp指向p,获取p中存储的值
     
     *(*pp) == *p = a;
     
     **pp == *p = a
     */
    **pp = 20;
    
    printf("%d\n",a);
    
    //int ***ppp = &pp;
    
    /*
     char a2 = 'A';
     char *p2 = &a2;
     */
    return 0;
}



2>指向指针的指针示意图


ios14指针控制是什么意思 ios 指针_ios14指针控制是什么意思_02

5.利用指针完成加减法

#include <stdio.h>

int sumAndMinus (int n1 ,int n2 ,int *n3);

int main(int argc, const char * argv[])
{
    int a = 10;
    int b = 7;
    int he ,cha;
    
    he = sumAndMinus(a, b, &cha);
    
    printf("%d  %d",he , cha);
    return 0;
}

int sumAndMinus (int n1 ,int n2 ,int *n3)
{
    *n3 = n1 - n2;
    
    return n1 + n2;
}



6.关于指针的疑问

1>函数例子

/*
 %d int
 %f float/double
 %ld long
 %lld long long 
 %c char
 %s 字符串
 %zd unsigned long
 */
#include <stdio.h>

int main(int argc, const char * argv[])
{
   //这里看内存分析图,如若不明白再看视频,讲解很详细
    //0000 0000 0000 0000 0000 0000 0000 0010 
    int i = 2;
    
    //0000 0001
    char c = 1;
    
    //char *p;
    int *p;//这里定义的char c,指针却用int *p,内存图分析原因为什么不行
    p = &c;
    
    //*p = 10
    
    printf("c的值是%d\n",*p);
    
    return 0;
}

void test()
{
    char c;//1字节
    int a;//4字节
    long b;//8字节
    
    //任何指针都占用8个字节的存储空间
    char *cp;
    int *ap;
    long *bp;
    
    //因为这里返回默认是unsigned long的值,所以返回字符%zd
    printf("cp=%zd , ap=%zd , bp=%zd\n",sizeof(cp),sizeof(ap),sizeof(bp));
    
    //这里的返回值显示不管什么类型指针都占用8个字节
}



2>指针在内存中示意图



ios14指针控制是什么意思 ios 指针_ios14指针控制是什么意思_03

7.指针与数组

1>函数例子

#include <stdio.h>

/*
 int ages[5];
 int *p;
 p = ages;
 
 1.数组元素的访问方式
 1>数组名[下标] ages[i]
 2>指针变量名[下标] p[i]
 3>*(p + i)
 
 2.指针变量的+1究竟加多少,取决于指针的类型
 int *    4字节
 char *    1字节
 double *    8字节
 
 */

void change(int array[]);
void test();

int main(int argc, const char * argv[])
{
    //20个字节
    int ages[] = {10 , 9 , 8 , 67 ,56};
    
    change(ages);
    test();
    return 0;
}

//利用一个指针来接受一个数组,指针变量array指向了数组的首元素

void change(int *array)
{
    printf("%d\n",array[2]);
    //printf("%d\n",*(array + 2));
}


 void test()
 {
     double d = 10.8;
     double *dp;
     dp = &d;
     
     printf("dp = %p\n",dp);
     printf("dp + 1 = %p\n",dp + 1);//这里dp + 1表示地址指向下一位
     
     int ages[] = {10 , 9 , 8 , 67 ,56};
     
     int *p;
     //指针变量p指向数组首元素
     p = &ages[0];
     //数组名就是数组的地址,也是数组首元素的地址
     //p = ages;
     
     /*
     p --->&ages[0]
     p + 1 --->&ages[1]
     p + 2 --->&ages[2]
     p + i --->&ages[i]
     */

    printf("%d\n",*(p+2));

    printf("%d\n",p[2]);

    /*
     for (int  i = 0; i < 5; i++) {
     printf("ages[%d] = %d\n",i ,ages[i]);
     }*/
}



2>指针遍历数组示意图


ios14指针控制是什么意思 ios 指针_ios14指针控制是什么意思_04

8.指针与字符串

#include <stdio.h>
/*
 1.常量区
 存放一些常量字符串,这里的字符串一般不能修改
 
 2.堆
 对象
 
 3.栈
 存放局部变量
 */

/*
 1>利用数组
 char name[] = "itcase";
 *特点:字符串里面的字符是可以修改的
 *使用场合:字符串的内容需要经常修改
 
 2>利用指针
 char *name = "itcase";
 *特点:字符串其实是一个常量字符串,里面的字符是不嫩修改
 *使用场合:字符串的内容不需要修改,而且这个字符串经常使用
 */

int main(int argc, const char * argv[])
{
    char name[20];
    
    printf("请输入名字:\n");
    
    scanf("%s",name);
    
    printf("刚才输入的字符串是:%s\n",name);
    return 0;
}

//定义字符串数组
void test2()
{
    char *name = "jack";
    
    //int ages[5];
    
    //指针数组(字符串数组)
    char *names[5] = {"jack","rose","jake"};
    
    //二维字符数组(字符串数组)
    char names2[2][10] = {"jack","rose"};

}


//定义字符串
void test()
{
    
    //字符串变量
    char name[] = "it";
    
    name[0] = 'T';
    
    printf("%s\n",name);
    
    //"it" == 'i' + 't' + '\0'
    //指针变量name2指向了字符串的首字符
    //字符串常量
    char *name2 = "it";
    
    char *name3 = "it";
    
    //    *name2 = 'T';
    
    //printf(%c\n,*name2);
    printf("%s\n",name2);

}



9.返回指针的函数

/*
 只要求看懂
 */

#include <stdio.h>

char *test();

int main(int argc, const char * argv[])
{

    char *name = test();
    printf("name = %s\n",name);
    return 0;
}

char *test()
{
    return "rose";
}



10.指向函数的指针

#include <stdio.h>

/*
 掌握:
 1.看懂语法
 2.定义指向函数的指针
    double (*p)(double , char *,int);
    p = haha;
    或者
    double (*p)(double ,char *,int) = haha;
 3.如何间接调用函数
 1>p(10.7 , "jack",10)
 2>(*P)(10.7 , "jack",10);
 */

void test()
{
    printf("调用了test函数\n");
}

int sum(int a ,int b)
{
    return a + b;
}
int main(int argc, const char * argv[])
{
    //定义指针变量指向sum函数
    //左边的int:指针变量p指向的函数返回int类型的数据
    //右边的(int ,int):指针变量p指向的函数有2个int类型的形参
    int (*p)(int ,int);
    
    p = sum;
    
    //int c = p(10 ,11);
    
    int c = (*p)(10 ,11);
    
    printf("c is %d\n",c);
    
    return 0;
}

void test1()
{
    //(*p)是固定写法,代表指针变量p指向的函数没有返回值
    //左边的void:指向变量p指向的函数没有返回值
    //右边的():指针变量p指向的函数没有形参
    void (*p)();
    
    //指针变量p指向了test函数
    p = test;
    
    p();
    //(*p)();//利用指针变量间接调用函数
    
    //test();//直接调用函数
}