函数
void print1(){
printf("Haha,\n");
printf("Good idea!\n");
}
void是返回类型,含义是“空”,即不返回任何东西
print1后面小括号没有任何参数,即无参函数
int main(){
print1();
return 0;
}
输出结果:
Haha,
Good idea!
有参函数的例子:
int judge(int x){
if(x > 0) return 1;
else if(x == 0) return 0;
else return -1;
}
judge()函数有了返回类型,即int型
局部变量:定义在函数内部,函数结束时局部变量销毁
再谈main函数
整个程序一定是从主函数的第一个语句开始执行
以数组作为函数参数
参数中数组的第一维不需要填写长度,如果是二维数组,那么第二维需要填写长度
数组作为参数时,在函数中对数组元素的修改就等同于是对原数组元素的修改,这与普通的局部变量不同
函数的嵌套调用
int max_2(int a, int b){
if(a > b) return b;
else return b;
}
int max_3(int a, int b, int c){
int temp = max_2(a, b);
temp = max_2(temp, c);
return temp;
}
int main(){
int a, b, c;
scanf("%d%d%d", &a, &b, &c);
printf("%d\n", max_3(a,b,c));
return 0;
}
函数的递归调用
即函数自己调用自己的过程
int F(int n) {
if(n ==0) return 1;
else return F(n - 1) * n;
}
int main(){
int n;
scanf("%d",&n);
printf("%d\n",F(n));
return 0;
}
输入3
输出6 即3!=6
指针
指针就是变量(房间)的地址(房间号)
只要在变量前面加上&,就表示变量的地址
输出变量地址
int a = 1;
printf("%d, %d\n", &a, a);
return 0;
输出结果2686748,1
指针是一个unsigned类型的整数
指针变量
用来存放指针(地址)
*可以放在变量前或后
需要挨个定义
int *p1, *p2, *p3;
给指针变量赋值的方式一般是把变量的地址取出来,然后赋给对应类型的指针变量
把星号视为一把开启房间的钥匙,将其加在p前面,这样*p就能把房间打开,然后获取a的值
int a
int* p = &a;
a = 233;
printf("%d\n", *p);
return 0;
但地址&a的值是赋给了p而不是*p,记住星号是类型的一部分
直接对*p进行赋值:令指针变量p存放a的地址,然后直接对*p进行赋值。于是 *p和a都会输出那个值
int a;
int* p = &a;
*p = 233;
printf("%d, %d\n, *p, a);
return 0;
输出结果
233,233
对int*型指针变量p来说,p+1是指所指的int型变量的下一个int型变量地址(跨越了一整个int型(即4Byte))
指针变量支持自增自减操作
指针与数组
数组名称也作为数组的首地址使用
int a[10] = {1};
int* p = a;
printf("%d\n",*p);
return 0;
输出结果 1,因此输出*p就是输出a[0]
指针变量可加减则a+i等于&a[i],但若要访问元素则要加上星号变为*(a+i)才和a[i]等价
输出数组元素
scanf("%d", a + i);
枚举数组中的元素
int a[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
for(int*p = a; p < a + 10; p++){
printf("%d ", *p);
}
return 0;
输出结果:1 2 3 4 5 6 7 8 9 10
两个指针相减,等价于两个指针之间相差几个int(两个地址间的距离)
如
int* p = a;
int* q = &a[5];
printf("q - p = %d\n", q - p)
return 0;
输出结果为5
使用指针变量作为函数参数
把变量的地址传入函数,如果在函数中对这个地址地元素进行改变,原先的数据就会改变
void change(int* p){
*p = 233;
}
int main(){
int a = 1;
int* p = &a;
change(p);
printf("%d\n", a);
return 0;
}
输出结果233,即使用*p修改地址中存放的数据。这种传递方式被称为地址传递。
交换功能如果不使用地址写成函数,无法影响main函数,因为它是单项一次性的值传递
只有在获取地址的情况下对元素进行操作,才能真正地修改变量。如下:
void swap(int* a, int* b){
int temp = *a;
*a = *b;
*b = temp;
}
int main(){
int a = 1, b = 2;
int *p1 = &a, *p2 = &b;
swap(p1, p2);
printf("a = %d, b = %d\n", * p1, *p2);
return 0;
}
解释:&a,&b(即ab的地址)作为参数传入,使swap函数中int*型指针变量a存放&a、指针变量b存放&b。
swap函数中的ab都是地址,而*a和*b就是地址中的数据
错误一:
void swap(int* a, int* b){
int* temp;
*temp = *a;
*a = *b;
*b = *temp;
}
这是因为temp没有被初始化,所以指针变量temp中存放的地址是随机的。改为:
void swap(int* a, int* b){
int x;
int* temp = &x;
*temp = *a;
*a = *b;
*b = *temp;
}
错误二:
void swap(int* a, int* b){
int* temp = a;
a = b;
b = temp;
}
这样做不能修改main函数里的地址
而能使main函数里的数据发生变化的只能是swap函数中对地址指向的数据进行的修改
引用
是C++中的语法,引用不产生副本,相当于一个人的两个名字,且对引用变量的操作就是对于原变量的操作。
使用方式:在哈数参数类型后面加一个&
void change(int&x){
x = 1;
}
int main(){
int x = 10;
change(x);
printf("%d\n", x);
return 0;
}
输出结果1
不管是否使用引用,函数的参数名和实际传入的参数名可以不同。比如上述main函数中的x也可以写成a
注意虽然符号相同,但引用并不是取地址的意思
指针的引用
错误写法二可改为
void swap(int* &p1, int* &p2){
int* temp = p1;
p1 = p2;
p2 = temp;
}
int main(){
int a = 1, b = 2;
int *p1 = &a, *p2 = &b;
swap(p1, p2);
printf("a = %d, b = %d\n, *p1, *p2);
return 0 ;
}
可以把int*型理解成unsigned int型
由于引用式产生变量的别名,因此常量不可使用引用,所以不能写成swap(&a,&b),必须用指针变量p1和p2存放&a,&b,然后把指针变量作为参数传入
如果理解遇到困难,可以先把引用去掉,看看原意是什么,再加上引用