函数
函数有两个及以上的形参时,当主函数调用函数进行传参时顺序是自右向左的。
在C语言中不加类型说明的函数,自动按整形处理。
值传递:在函数调用过程中对形参的修改不能影响到实参本身 及被调函数不能修改主调函数。形参 和 实参 不是同一个内存空间。
指针传递:数组名可以作为实参和形参,传递的是数组首元素的地址。
例: fn (10); 可以传参一个常量,fn函数不可能将常量10的值给修改了,所以fn中的形参是另外的内存空间复制的 常量10。
当程序在主函数中调用子函数时,系统pc寄存器会先保存当前指令的地址,然后加载子函数首个指令的地址,然后程序运行跳转到子函数的首个指令。
子函数的镶嵌结构 为 栈 FILO 先进后出。这就是栈区,他保存了函数调用需要保存的地址,保存了形参空间和函数所有变量。
栈区大小在linux里一般是8M,在windows里一般是1M。
递归函数
例:求1+到N的合。
当一维数组作为实参传递给子函数时,不能再子函数内计算出数组的长度,传递给子函数的是首元素地址,所有需要在主函数加一个参数 数组长度 一起传给子函数。
数组进行实参传递属于指针传递,被调函数可以改实参。
代码练习:
e1.自己编写strcpy、strcmp等函数,用二维字符型数组作为函数参数,实现多个字符串的逆序,排序和二分查找。
#include<stdio.h>
void myputs(char s[])
{
int i = 0;
while(s[i] != '\0')
{
putchar(s[i]);
++i;
}
putchar('\n');
}
int mystrlen(char s[])
{
int counter = 0;
while(s[counter] != '\0')
{
++counter;
}
return counter;
}
void mystrcpy(char dest[], char src[])
{
int i = 0;
while(src[i] != '\0')
{
dest[i] = src[i];
++i;
}
dest[i] = '\0';
}
void mystrcat(char dest[], char src[])
{
int i, j;
for(i = 0; dest[i] != '\0'; ++i);
for(j = 0; src[j] != '\0'; ++j)
{
dest[i] = src[j];
++i;
}
dest[i] = '\0';
}
int mystrcmp(char s1[], char s2[])
{
int i = 0;
while(s1[i] == s2[i] && s1[i] && s2[i])
{
++i;
}
return s1[i] - s2[i];
}
int printArray2D(int a[][4], int rows)
{
int i, j;
int cols = sizeof(a[0]) / sizeof(a[0][0]);
for(i = 0; i < rows; ++i)
{
for(j = 0; j < cols; ++j)
{
printf("%2d ",a[i][j]);
}
printf("\n");
}
}
int sumSoundArray2D(int a[][4], int rows)
{
int cols = sizeof(a[0]) / sizeof(a[0][0]);
int i, j, sum = 0;
for(i = 0; i < rows; ++i)
{
for(j = 0; j < rows; ++j)
{
if(0 == i || i == rows - 1 || 0 == j || j == cols - 1)
{
sum += a[i][j];
}
}
}
return sum;
}
void reverse2D(int a[][4], int rows)
{
int cols = sizeof(a[0]) / sizeof(a[0][0]);
int i,j;
for(i = 0; i < rows; ++i)
{
for(j = 0; j < cols / 2; ++j)
{
int t = a[i][j];
a[i][j] = a[i][cols -j -1];
a[i][cols -j -1] = t;
}
}
}
void printString(char s[][100], int rows)
{
int i = 0;
for(i = 0; i < rows; ++i)
{
myputs(s[i]);
}
}
void reverseStrings(char s[][100], int rows)
{
int i,j;
char t[100];
int cols = sizeof(s[0]) / sizeof(s[0][0]);
for(i = 0; i < rows / 2; ++i)
{
mystrcpy(t,s[i]);
mystrcpy(s[i],s[rows - i -1]);
mystrcpy(s[rows - i -1],t);
}
}
void sortStrings(char s[][100], int rows)
{
int i,j;
for (i = 0; i < rows; ++i)
{
for(j = i + 1; j < rows; ++j)
{
if(mystrcmp(s[i],s[j]) > 0)
{
char t[100];
mystrcpy(t,s[i]);
mystrcpy(s[i],s[j]);
mystrcpy(s[j],t);
}
}
}
}
int binaryFindString(char s[][100], int rows, char n[])
{
int begin = 0, end = rows - 1;
int mid;
while(begin <= end)
{
mid = (begin + end) / 2;
if(mystrcmp(s[mid], n) > 0)
{
end = mid - 1;
}
else if(mystrcmp(s[mid],n) < 0)
{
begin = mid + 1;
}
else
{
return mid;
}
}
return -1;
}
int main(int argc, const char *argv[])
{
char s[][100] = {"Hello","World!","China","Amercia"};
int rows = sizeof(s) / sizeof(s[0]);
sortStrings(s,rows);
char n[100] = "Amercia";
// int ret = binaryFindString(s,rows,n); 二分查找
// if(ret == -1)
// {
// printf("not found\n");
// }
// else
// {
// printf("s[%d] = ",ret);
// myputs(s[ret]);
// }
// sortStrings(s,rows);
reverseStrings(s,rows);
printString(s,rows);
// int a[][4] = {1,2,3,4,5,6,7,8,9,10,11,12,13};
// int rows = sizeof(a) / sizeof(a[0]);
// reverse2D(a,rows);
// int sum = sumSoundArray2D(a,rows);
// printf("%d\n",sum);
// printArray2D(a, rows);
// char s1[] = "Hello";
// char s2[] = "World!";
// printf("%d\n",mystrcmp(s1,s2));
// mystrcat(s1,s2);
// myputs(s1);
// printf("%d\n",mystrlen(s2));