• c知识点总结2


    函数

    int func(int x){        //x:形式参数
        ....
    }
    
    
    int main(){
        ....
        int res=func(z);    //z:实际参数
    }

    实参与形参具有不同的存储单元,

    实参与形参变量的数据传递是“值传递”;

    函数调用时,系统给形参分配存储单元,并将实参对应的值传递(copy)给形参;

    P.S. 实参与形参的类型必须相同或可以兼容;

    示例:

    #include<iostream>
    using namespace std;
    void exchange(int a, int b){
        int p;
        p = a; a = b; b = p;
    }
    int main(){
        int a = 3, b = 5;
        exchange(a, b);
        cout<<a<<" "<<b<< endl;
        return 0;
    }

    输出结果将会是3 5.  因为在调用exchange()时,main函数里的a和b的值被copy给exchange(),然后修改的是exchange函数内存空间里的a和b,而不是main函数内的。那如何实现exchange功能呢?可以用指针

    #include<iostream>
    using namespace std;
    void exchange(int *a, int *b){
        int p;
        p = *a; *a = *b; *b = p;
    }
    int main(){
        int a = 3, b = 5;
        exchange(&a, &b);
        cout<<a<<" "<<b<< endl;
        return 0;
    }
    View Code

    如果是数组作为函数参数呢?

    #include <iostream>
    using namespace std;
    void change(int a, int b){
        a = 30; b = 50;
    }
    int main()
    {
        int a[2] = {3, 5};
        change(a[0], a[1]);
        cout<<a[0]<<" "<<a[1]<<endl;
        return 0;
    }

    这里数组元素a[0]和a[1]和普通变量一样,是直接值拷贝过去的。所以输出还是3 5
    #include <iostream>
    using namespace std;
    void change(int z[]){
        z[0] = 30; z[1] = 50;
    }
    int main(){
        int a[2] = { 3, 5 };
        change(a);
        cout << a[0] <<" "<< a[1] << endl;
        return 0;
    }

    返回结果是30 50. 这里参数传递的时候copy的是数组a的名字(a是一个常量,表示数组a在内存中的地址)。这样change函数内就直接找到a[0]和a[1]对应的内存空间进行修改了。

    函数执行结束之后,函数内的所有内容(eg 局部变量)都会被销毁


    指针

    &x  取变量x的地址

    *p  取地址p中的内容

    *&x   等价于   x

    int *p;                    //指针变量,存放地址。    
    int c=888;
    int d=999;
    int e=233;
    p=&c;                      //表示把c的地址赋给p
    cout<<c<<" "<<*p<<endl;    //888 888
    *p=666;                    //表示把p所指向的存储单元(也就是c)的内容改成666
    cout<<c<<" "<<*p<<endl;    //666 666 
    c=d;                       //再改成999
    cout<<c<<" "<<*p<<endl;    //999 999 
    *p=e;                      //再改成233
    cout<<c<<" "<<*p<<endl;    //233 233 

     两个例子:

     1     int ic=18;
     2     int *ip=&ic;
     3     *ip=58;
     4     cout<<ic<<endl;
     5     cout<<ip<<endl;
     6     cout<<&ic<<endl;
     7     cout<<*ip<<endl;
     8     cout<<&ip<<endl;    //指针变量的地址
     9 
    10 Output: 
    11 58
    12 0x7ffe4b072e04
    13 0x7ffe4b072e04
    14 58
    15 0x7ffe4b072e08
    16 
    17 ---------------------------------------------------
    18 
    19     int a=9,b=3;
    20     int *p1=NULL, *p2=NULL;
    21     int *tmp=NULL;
    22     p1=&a;
    23     p2=&b;
    24     if(*p1>*p2){
    25         tmp=p1;  p1=p2;  p2=tmp;        //交换的是p1和p2两个指针
    26     }
    27     cout<<*p1<<" "<<*p2<<endl;
    28     cout<<a<<" "<<b<<endl;
    29 
    30 3 9
    31 9 3
    View Code

    对指针变量做++的含义:  int *p;    p++;    //p=p+(sizeof(int));

    指向数组的指针:   

    int a[10];   int *p;   p=a;

    【 数组名相当于指向数组第一个元素的指针】
    如果有一个  int a[4]={1,2,3,4};

    • 若 a 是 指向数组第一个元素 的指针, 即a相当于&a[0];
    • a是指向a[0]的指针,a+1将跨越sizeof(int)=4个字节
    • &a是“指向数组”的指针; &a+1将跨越4*sizeof(int)=16个字节;
      • &a 相当于 管辖范围“上升” 了一级;
    • *a 是数组的第一个元素a[0];即*a等价于a[0] ;
      • *a 相当于 管辖范围“下降” 了一级;

    二维数组的指针

    int a[3][3]={{1,2,3}, {4,5,6}, {7,8,9}};

    a[0]  -  a[0][0] a[0][1] a[0][2]

    a[1]  -  a[1][0] a[1][1] a[1][2]

    a[2]  -  a[2][0] a[2][1] a[2][2]

    a[0]是指向数组{a[0][0], a[0][1], a[0][2]}的第一个元素a[0][0]的指针,管辖范围 = sizeof(a[0][0]) = sizeof(int)

    a是指向数组{a[0], a[1], a[2]}的第一个元素a[0]的指针,管辖范围 = sizeof(a[0]) = 3*sizeof(int)

    &a是指向整个数组a的指针,管辖范围 = sizeof(a) = 9*sizeof(int)

    • a与&a[0]等价
    • a[0]与&a[0][0]等价
    • a[0]与*a等价
    • a[0][0]与**a等价
       
    • 数组名相当于指向数组第一个元素的指针
    • &E 相当于把E的管辖范围上升了一个级别
    • *E 相当于把E的管辖范围下降了一个级别

    指针操作字符串

    char buf[10]="ABC";
    char *pc;
    pc="hello";            //hello是常量,不能修改
    cout<<pc<<endl;        //hello
    pc++;
    cout<<pc<<endl;        //ello
    cout<<*pc<<endl;       //e
    pc=buf;                //相同类型指针之间的赋值
    cout<<pc<<endl;        //ABC

     指针作为函数参数

    #include <iostream>
    using namespace std;
    
    int maxvalue(int (*p)[4])        //p和a类型一样,是指向a[0]的指针
    //int maxvalue(int p[][4]) //这样也可以。c编译器将形参数组名作为指针变量来处理
    { int max = p[0][0]; for(int i=0; i<3; i++) for(int j=0; j<4; j++) if(p[i][j]>max) max = p[i][j];
    *p[i]
    return max; } int main( ) { int a[3][4] = {{1,3,5,7},{9,11,13,15},{2,4,6,8}}; cout<<"The Max value is "<<maxvalue(a); return 0; }
    int maxvalue(int p[])
    //int maxvalue(const int p[])           //如果想限制对原数组的修改,可以加const
    {
        int max = p[0];
        for(int j=0; j<4; j++)
            if(p[j]>max)
                max = p[j];
        *p=666;                           //可以这样修改原数组的值
        return max;
    }
    int main( )
    {
        int a[4] = {2,4,6,8};
        cout<<"The Max value is "<<maxvalue(a)<<endl;
        cout<<a[0]<<endl;    //666
        return 0;
    }
    void mystrcpy(char *dest, const char *src){
        ......
        //保证src不会被修改
    }
    int main(){
        char a[20] = “How are you!”;
        char b[20];
        mystrcpy(b,a);
        cout<<b<<endl;
        return 0;
    }
    int main(){
        const int a=78;
        const int b=58;
        int c=28;
        
        const int *pi=&a;
        *pi=58;     //不可以,*p是a,不能修改
        pi=&b;      //可以。p本身是可以修改的
        *pi=68;     //不可以。*p是b,不能修改
        pi=&c;      //不可以。c是int,而pi是指向const int的指针
        *pi=88;     //不可以
    }

    指针用做函数返回值

    #include <iostream>
    using namespace std;
    
    int *get(int arr[ ][4], int n, int m){
        int *pt;
        pt = *(arr + n - 1) + m-1;      //arr+n-1是指向int[4] {5,6,7,8}的指针,加一个*获取这个小数组的地址
        return(pt);
    }
    
    int main(){
        int a[4][4]={1, 2, 3, 4, 
                     5, 6, 7, 8, 
                     9, 10, 11, 12, 
                     13, 14, 15, 16};
        int *p;
        p = get(a, 2, 3);
        cout<<*p<<endl;
    }

    静态局部变量:函数中的局部变量的值在函数调用结束后不消失而保留原值,即其占用的存储单元不释放。在下一次该函数调用时,仍可以继续使用该变量;

    #include <iostream>
    using namespace std;
    
    int *getInt1(){
        static int value1 = 20;
        return &value1;
    }
    int *getInt2(){
        static int value2 = 30;
        return &value2;
    }
    void func(){
        int a=0;
        static int b=0;                  //整个程序运行周期中只执行一次。函数退出后仍然保留b的值
        a++;
        b++;
        cout<<a<<" "<<b<<endl;
    }
    
    int main(){
        int *p,*q;
        p = getInt1();
        q = getInt2();
        cout << *p << endl;
        cout << *q << endl;
        for(int i=0;i<5;i++){
            func();
        }
        return 0;
    }
    
    --------------------------------
    output:
    20
    30
    1 1
    1 2
    1 3
    1 4
    1 5

     111

  • 相关阅读:
    GithubPlus+PicGo + Typora 一键式图床
    快速掌握Linux这篇文章就够了。
    跨行程序员Java进阶--基础语法
    Prometheus(普罗米修斯)
    【学习记录】Golang
    服务器Docker-Compose 安装 Anaconda
    Kubernetes集群部署
    Jenkins部署
    Harbor部署
    Docker、Docker-Compose的安装以及相关使用
  • 原文地址:https://www.cnblogs.com/pdev/p/11301158.html
Copyright © 2020-2023  润新知