C语言系列(23)——函数(02)
一、传值和传址
参数的传递有两种方式,传变量的值
、传变量的地址(指针)
。
-
- 值传递
例:定一个函数,对传入的两个整型值,输出较大的那个。
void printMax(int a, int b);//函数声明
int main()
{
int a = 10, b = 20;
printMax(a, b);//函数调用,实参传递
system("pause");
return 0;
}
void printMax(int a, int b)//函数定义
{
if (a > b)
printf("max:%d\n", a);
else if (a < b)
printf("max:%d\n", b);
else
printf("equal");
}
上述案例,函数参数只是普通的值
的传递。
-
- 地址(指针)传递
例:定义一个函数,对传入的两个整型值进行交换。
错误示例:
void swap(int a, int b);//函数声明
int main()
{
int a = 10, b = 20;
swap(a, b);//函数调用,实参传递
printf("a:%d, b:%d\n", a, b);
system("pause");
return 0;
}
void swap(int a, int b)//函数定义
{
int tmp = a;
a = b;
b = tmp;
}
打印a:10, b:20
注意: 结果显示,通过调用swap函数,并没有显示main函数中a、b两个变量的交换。
因为这个函数定义只是进行了值的传递,swap函数中进行交换只是交换了局部变量的值。
交换函数如下定义:
void swap(int *a, int *b);//函数声明
int main()
{
int a = 10, b = 20;
swap(&a, &b);//函数调用,实参传递,传递地址
printf("a:%d, b:%d\n", a, b);
system("pause");
return 0;
}
void swap(int *a, int *b)//函数定义,形参为指针类型,接受传递过来的地址(指针)
{
int tmp = *a;
*a = *b;
*b = tmp;
}
-
- 例:地址(指针)传递2
函数:实现数组排序
void arrAscSort(int arr[], int size);//第一个参数也可以写成,int * arr
int main()
{
int arr[10] = { 3,4,6,2,7,8,9,1,0,10 };
arrAscSort(arr, 10);//传地址(指针)
for (int i = 0; i < 10; i++)
{
printf("%d ", arr[i]);
}
system("pause");
return 0;
}
void arrAscSort(int arr[], int size)//数组类型作为参数,实际是传递地址(指针)
{
int i = 0;
int j = 0;
for ( i = 0; i < size; i++)
{
for ( j = size-1; j > i; j--)
{
if (arr[j] < arr[j - 1])
{
int tmp = arr[j];
arr[j] = arr[j - 1];
arr[j - 1] = tmp;
}
}
}
}
二、返回地址(指针)
- 函数:结束用户输入的10个数,并返回给调用者。
错误示例:
int* resArr()
{
int arr[10] = { 0 };
int i = 0;
for (i = 0; i < 10; i++)
{
scanf_s("%d", &arr[i]);
}
return arr;//arr是局部变量,随着函数的结束会被销毁,返回无意义
}
int main()
{
int i = 0;
int *p = resArr();//返回的内存地址,被回收了
for (i = 0; i < 10; i++)
{
printf("%d ", *(p + i));
}
system("pause");
return 0;
}
正确示例:
int* resArr()
{
//int arr[10] = { 0 };
int* arr = (int*)malloc(sizeof(int) * 10);//堆空间可以返回
int i = 0;
for (i = 0; i < 10; i++)
{
scanf_s("%d", &arr[i]);
}
return arr;//arr是局部变量,随着函数的结束会被销毁,返回无意义
}
int main()
{
int i = 0;
int *p = resArr();
for (i = 0; i < 10; i++)
{
printf("%d ", *(p + i));
}
free(p);//注意释放
system("pause");
return 0;
}
三、练习
-
- 实现strcpy功能
char* myStrcpy(char* des, const char* sou)
{
char *p = des;
if (NULL == des || NULL == sou)
{
return NULL;
}
while (*sou != 0)
*p++ = *sou++;
*p = 0;
return des;
}
-
- 实现strcat功能
char* myStrcat(char* des, const char* sou)
{
int len = strlen(des);
int i = 0;
if (NULL == des || NULL == sou)
{
return NULL;
}
while (*(sou+i) != 0)
{
*(des + len + i) = *(sou + i);
i++;
}
*(des + len + i) = 0;
return des;
}
-
- 实现strstr功能
const char* myStrstr(const char* str, const char* subStr)
{
int i, j, k;
int len1 = strlen(str);
int len2 = strlen(subStr);
if (NULL == str || NULL == subStr)
return NULL;
for (i = 0; i < len1; i++)
{
for ( j = 0, k = i; j < len2; j++, k++)
{
if (subStr[j] != str[k])
break;
if (subStr[j] == str[k] && len2 - 1 == j)
return str + i;
}
}
return NULL;
}