函数
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;
}
如果是数组作为函数参数呢?
#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=⁣
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
对指针变量做++的含义: 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
