1、c语言中函数的参数
01、c语言中实参向形参的传递过程是单向传递的,在对形参进行修改后的值不能返回给实参。
02、函数返回调用源的返回值只能有一个。
例、求两个数的和与差。
#include <stdio.h> void sum_diff(int x, int y, int sum, int diff) { sum = x + y; diff = (x > y) ? (x - y) : (y - x); } int main(void) { int a, b, wa = 0, sa = 0; puts("please input two integers."); printf("a = "); scanf("%d", &a); printf("b = "); scanf("%d", &b); sum_diff(a, b, wa, sa); //wa,sa作为实参传递给形参sum和diff,sum和diff在调用函数时重新进行了赋值,但是并不能返回给函数的调用位置main函数中的变量。(实参→形参,单向复制) // wa和sa的值仍然是在main函数中的值0. printf(" wa: %d || sa: %d ", wa, sa); return 0; }
为了解决这个问题(对传入函数中的变量的值进行修改,并返回调用源),需要c语言中的指针。
2、对象和地址
001、对象是不是就是变量???
002、变量拥有多种属性:数据类型、存储期、变量名等。
003、对象:继承了变量属性而创建的变量实体称为对象。
004、地址:指的是对象的地址。 对象在内存上的存储位置编号。 本质:存储位置编号(指针)。
3、取址运算符
001、取址运算符:单目运算符 &称为取址运算符。
002、将取址运算符放在对象(变量)的前面,就可以获得对象的地址(存储位置编号)。
003、取址运算符&的作用是获取对象的地址,生成指向对象的指针。(与其说是获取地址,不如说是生成指针)。
004、对象地址的转换说明为%p,其中p为pointer的首字母。
005、取址运算符&写在Type型变量x的前面,&x为Type*型指针,其值为x的地址。
示例程序如下:
#include <stdio.h> int main(void) { int n; double x; int a[3]; printf("nnnn: %p ", &n); //&取址运算符,获取地址,生成指向对象(n)的指针 printf("xxxx: %p ", &x); //%p为对象地址的转换说明,p为pointer的首字母 printf("a[0]: %p ", &a[0]); printf("a[1]: %p ", &a[1]); printf("a[2]: %p ", &a[2]); return 0; }
4、指针运算符
001、单目运算符*称为指针运算符。
002、指针运算符的作用:1、生成指针变量,eg:int *x; 生成指针变量x,2、获取指针所指对象的值。 eg: *p,获取指针p所指对象的值。
003、当指针p的值为对象x的地址时,说p指向x, *p为x的别名。
程序:
#include <stdio.h> int main(void) { int a = 100; int b = 200; int c = 500; int *x, *y; //指针变量声明,声明x、y均为指向int型变量的指针。 x = &a; y = &c; //生成指针,x为a的地址,x指向a,y为c的地址,y指向c。 printf("xxxx: %d ", *x); // 在指针前使用指针运算符,用于获取指针所指对象的值,x指向a,因此为a的值。 printf("yyyy: %d ", *y); //同理,y执行c,因此为c的值。 x = &b; //修改指针x,x由 是a的地址改为是b的地址,因此a由指向a该为指向b。 *y = 800; // 指针y是c的地址,y指向c,因此*y是c的别名,对*y重新赋值,相当于对c重新赋值。 puts(" =============== "); printf("aaaa: %d ", a); //对象a的值 printf("bbbb: %d ", b); //对象b的值 printf("cccc: %d ", c); //对象c的值,c有c的别名*y重新进行了赋值,c此时为800. printf("xxxx: %d ", *x); //x此时是指向b的指针,*x因此是对象b的值 printf("yyyy: %d ", *y); //*y作为c的别名,进行了重新赋值,值为800. return 0; }
指针p的值为对象x的地址时,p执行x,*p为x的别名,对别名进行修改,相当于对原始对象的修改。(应用于函数,在形参中反向修改实参?)