前言

  • 记录一下,c和c++中的指针和引用,并对两者做一下区分。

指针的定义和使用

  1. 指针的定义,指针是指向另外一种类型的复合类型,用来存放对象的地址
  2. 下面的程序中对指针pa进行了赋值,pb未进行赋值(此时pb可能就会对系统造成危险也被称之为野指针,内容随机)
    1
    2
    3
    4
    5
    6
    7
    int main(){
    int a = 1;
    int *pa = &a, *pb;

    printf("%d", *pa);//通过解引用取出pa存放地址里面的值
    return 0;
    }

指针的简单应用(变量内容交换)

  1. 若存在两个变量,我们该如何交换两个内容的值呢?(空杯换值:使用一个额外的空间来存放带交换的值)

    1
    2
    3
    4
    5
    void swap(int a, int b){
    int temp = a;
    a = b;
    b = temp;
    }
  2. 此时发现a, b的值并没有交换(因为传过来的实参,会在自定义函数中创建副本局部变量,函数结束时,这些局部变量会自动销毁除非z这里使用静态变量),那尝试使用指针就可以很好的解决这个问题。

    1
    2
    3
    4
    5
    void swap(int *a, int *b){
    int temp = *a;
    *a = *b;
    *b = temp;
    }
  3. 虽然上面的交换函数,确实实现了两个变量内容的交换,那我们在函数中改变指针指向的位置,是否也会改变内容呢?
    你会发现a的值并不会产生变化,这种传递指针的方式,也是和第一种方法一样将值传入,创建局部变量副本。不同的是,通过指针对内容进行了间接修改。

    1
    2
    3
    4
    5
    6
    void fun(int *a){
    int b = 1;
    int *pb = &b;

    a = pb;//改变了a指针指向的位置
    }
  4. 那么如何使用指针,在自定义函数内部改变指针指向位置,达到值的修改呢?
    可以通过使用上面的方式,创建一个指针的指针变量,通过改变变量的指向来修改指针指向的内容

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    void fun(int **ppa){
    int b = 3;
    int *pb = &b;

    *ppa = pb;
    }
    int main(){
    int a = 2;
    int *pa = &a;
    int **ppa = &pa;

    printf("%d\n", **ppa);
    fun(ppa);
    printf("%d\n", **ppa);
    }

指针和数组

  1. 数组的初始化和指针的分配(定义动态数组),也可以使用循环实现赋初值
  2. 使用指针来动态申请空间时,需先使用malloc函数动态的请求一块空间
  3. memset可以方便的对指针赋值void *memset(void *s, int ch, size_t n)函数解释:将s中当前位置后面的n个字节用 ch 替换并返回 s 。ch只能是0和-1

    1
    2
    3
    4
       int a[10] = {0};//定义一个整型数组,并置零

    int *p = (int *)malloc(sizeof(int)*10);
    memset(p, 0, sizeof(int)*10);
  4. c和c++中将数组名解释为数组中第一个元素的地址

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    int arr[10] = {1,2,3,4,5};
    int *p = arr;
    cout<<" -------------- 3 种方式得到数组的地址 ------------------- "<<endl;
    cout<<"arr -> "<<arr<<endl;
    cout<<"&arr[0] -> "<<&arr[0]<<endl;
    cout<<"p -> "<<p<<endl;
    cout<<" -------------- 4 种方式得到数组的值 ------------------- "<<endl;
    cout<<"arr[1] -> "<<arr[1]<<endl;
    cout<<"*(arr+1) -> "<<*(arr+1)<<endl;
    cout<<"*(p+1) -> "<<*(p+1)<<endl;
    cout<<"p[1] -> "<<p[1]<<endl;
  5. 指针数组和数组指针

  • 指针数组:array of pointers,即用于存储指针的数组,也就是数组元素都是指针
  • 数组指针:a pointer to an array,即指向数组的指针
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    #include<bits/stdc++.h>
    using namespace std;
    int main()
    {
    /*** 指针数组
    ** <数组 pstr[3],数组的元素是指针> 三省指针:指针的类型是 int * ,
    指向的类型是int ,数组内每个指针分别指向 三个字符串的首地址
    ***/
    char *pstr[3] = {
    "Socialism",
    "with",
    "Chinese"
    };
    cout<<" pstr[0] "<<pstr[0][0]<<endl;;
    cout<<" pstr[1] "<<pstr[1]<<endl;;
    cout<<" pstr[2] "<<pstr[2]<<endl;;

    /*** 数组指针
    ** <指针 pstr1> 三省指针:指针的类型是 int (*)[20] ,
    指向的类型是int()[20] ,指针指向 str1
    ***/
    char str1[20] = "Characteristics";
    char (*pstr1)[20] = &str1;
    //b=&str1;
    cout<<" *pstr1 "<<*pstr1<<endl;;
    }

字符串数组和指针

  1. 数组的大小一定要大于字符串的长度,因为系统会自动补上一个’\0’作为字符串的结束标志。当然对于未初始化的也补’\0’.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    int main()
    {
    char ar[]={'a','b','c','d'};
    printf("%s", ar);
    printf("%s\n", br); //字符串后无结束符\0,会有多余打印

    char br[]={'a','b','c','d','\0'};
    printf("%s\n", br);

    char cr[5]="abcd"; //字符串结尾默认隐藏了\0
    printf("%s\n", br);

    return 0;
    }
  2. 利用字符串指针来赋值,但是字符串指针里的内容不能被修改

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    int  main(){
    char *p="hello world"; //hello world存放在内存的静态常量区
    //指针变量p存储的是该静态常量区的首个字符地址
    //不能通过指针修改静态常量区的字符,但是可以通过指针访问

    int length=strlen(p);
    //strlen计算的是字符串p的有效长度,不算\0

    for(int i=0;i<length;++i){
    cout<<p[i];
    }

    return 0;
    }
  3. 为了能修改指针数组的内容,可以使用字符串拷贝函数strcpy或内存拷贝函数进行拷贝

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    // 创建一个字符串数组
    char arr[10] = {0};
    // 创建一个指针,并指向静态区存放的一个字符串“ABC”
    char* tmp = "ABC";

    // 利用字符串拷贝函数进行拷贝
    strcpy(arr, tmp);

    // 例如内存拷贝函数进行拷贝
    memcpy(arr, tmp, sizeof(arr));

使用指针的好处

用指针可以带来如下的好处:

(1)可以提高程序的编译效率和执行速度,使程序更加简洁。
(2)通过指针被调用函数可以向调用函数处返回除正常的返回值之外的其他数据,从而实现两者间的双向通信。
(3)利用指针可以实现动态内存分配。
(4)指针还用于表示和实现各种复杂的数据结构,从而为编写出更加高质量的程序奠定基础。
(5)利用指针可以直接操纵内存地址,从而可以完成和汇编语言类似的工作。
(6)跟容易实现函数的编写和调用


参考链接

https://www.cnblogs.com/sxy-798013203/p/7754858.html
https://blog.csdn.net/dajiyi1998/article/details/80932397

留言

⬆︎TOP