• C语言指针


    #include<stdio.h>

    void change(int *); int main() { int a = 90; change(&a); printf("a = %d ", 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 ", *p); // 指针变量未经初始化,不要拿来间接访问其他的存储空间

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

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

    三、指向指针的指针

    int a = 10;

    int *p = &a; // 指向int型的指针

    int **p1 = &p; // 指向指针的指针

    int ***p2 = &p1; // 三级指针

    *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
    ", sum, minus);
        
    }

    五、有关指针的疑问

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

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

    int i = 2;

    char c = 1; 

    int *p = &c; // 本应该是char类型的,写成了int类型

    printf("c的值是%d ", *p); // 打印结果为513,而非1

    printf("c的值是%d ", c); // 值为1

    下面是上述代码的结果的内存分析:

    指针p访问的本应该是1个字节空间的数据,此时因为指针的类型是int型的,因此程序自然的从指向的地址0x0a开始读取了4个字节的数据,访问的数据从1变成了513。

    提示:明确了指针的数据类型,指针才能够正确的访问应该访问的空间数据。

    六、指针和数组

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

    遍历数组

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

    printf("%d ", 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 ", *(p + i));

    (1)数组元素的三种访问形式:

    ①. 数组名[下标]

    ②. 指针变量名[下标]

    ③. *(p + 1)

    (2)指针变量的+1究竟是加多少?这取决于指针的类型,如果是char类型则加1个字节,如果是int类型的,则加4个字节。

    (3)利用指针来接收一个数组,指针变量指向了数组的首元素。

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

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

    示例:

     1 #include <stdio.h>
     2 
     3 void change(int *array)
     4 {
     5     
     6     // printf("%d
    ", array[2]);
     7     
     8     printf("%d
    ", *(array+2));
     9     
    10 }
    11 
    12 int main()
    13 {
    14     
    15     int ages[5] = {1, 2, 3, 4, 5};
    16     
    17     change(ages);
    18     
    19 }

    调用的结果为:数组的第三个元素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 ", name); // 打印结果为yt

    *name2 = 'y';

    printf("%s ", 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"};

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

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

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

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

     1 #include <stdio.h>
     2 
     3 char *test();
     4 
     5 int main()
     6 {
     7     
     8     char *name = test();
     9     
    10     printf("name = %s
    ", name);
    11     
    12     return 0;
    13     
    14 }
    15 
    16 char *test() // 返回指针的函数
    17 {
    18     
    19     return "rose"20     
    21 }

    八、返回指针的函数

    程序示例:

    #include <stdio.h>
    
    char *test();
    
    int main()
    {
        
        char *name = test();
        
        printf("name = %s
    ", name);
        
        return 0;
        
    }
    
    char *test() // 返回指针的函数
    {
        
        return "rose";
        
    }

    九、指向函数的指针

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

    假设有函数:

    void test()

    {

        printf("调用了test函数 ");

    }

    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;

  • 相关阅读:
    Jquery fancybox 可以实现在当前页面弹出框
    http下载
    使用Fat 直接运行Java中自定义的main方法
    Tomcat 中配置直接请求(不带项目名请求)
    java 解压
    文件压缩到zip
    导出excel 头部文件
    NPOI 动态添加行
    ICSharpCode.SharpZipLib.Zip.ZipException: EOF in header
    elasticsearch配置
  • 原文地址:https://www.cnblogs.com/zengshuilin/p/5731261.html
Copyright © 2020-2023  润新知