Pentium.Labs

System全家桶:https://zhuanlan.zhihu.com/c_1238468913098731520

导航

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

 

posted on 2019-08-08 10:43  Pentium.Labs  阅读(220)  评论(0编辑  收藏  举报



Pentium.Lab Since 1998