嵌入式学习记录11

函数的嵌套调用:

特殊的嵌套调用 --- 递归 (自己调用自己)

递归 --就是循环

如从1加到100;

嵌入式学习记录11_第1张图片

反着来,直到找到初始值sum(1)= 1;  再回归得到最终的sum;

递推关系 :  重复的    第n项 与 第n-1项之间的关系 ;

斐波拉契数列前n项之和中:

用递归思想:

 fibo(n) = fibo(n-1) + fibo(n-2);

第三项等于前两项个之和;

而前n项和 : 则是 sum(n)   n>2     因为斐波拉契数列前两项均为一;是从第三项开始,所以此时fibo(2)==1; fibo(1) == 1; sum(2)==2;

 sum(n-1)+fibo(n)                //                  fibo(n) = fibo(n-1) + fibo(n-2);

    sum(n-2)+fibo(n-1)   // fibo(n-1) = fibo(n-2) + fibo(n-3)      fibo(n-2) = fibo(n-3) + fibo(n-4)    

                 ....                 |                     fibo(n-2) = fibo(n-3) + fibo(n-4)      ........

         sum(3)+fibo(4)      |                                       fibo(n-3) = fibo(n-4) + fibo(n-5)   .......

             sum(2)+fibo(3)   |                                                  .......

                     2+fibo(3)    |                                        fibo(4)=fibo(3)+(fibo(2)没有斐波2,此时fibo2=1);

                                                                                     fibo(3)=1+1;     

                                                                               最终全部反推回去,得到最终的sum(n);

                                                                     

一,数组作为函数参数:

1.数组元素作为函数实参 

1.2.一维整型数组作为函数的形参:

                此时函数的形参 是一个与实参类型相同变量即可 

1.2.1被调用函数 形参:

void printArray(int a[10]);   //此时 形式上看 是数组 

                                          //编译器最终 是当做指针变量来看的 

void printArray(int *a);     //实际是这样的 

注意一般要传两个变量:

一般为 :   void printArray(int a[],lint len);a[ ]括号中可以不写;

一个是数组形式    一个是数组长度

因为主函数传过来的是数组首元素的地址(a),需要长度来完成循环;

a[10]中 a 是该数组名,也是该数组首元素地址;即a[0]地址;

1.2.2实参: 

printArray(a,len); 

1.3.一维字符型数组做函数形参:

1.3.1被调用函数形参:

void printStr(char s[1000]); //形式上 写成字符数组的形式 

void printStr(char * s); //编译器最终当做指针变量处理

1.3.2实参:

            printStr(s);  //数组名  

                                //注意: 此时不需要传数组长度 ---因为字符串有结束标志 '\0';

1.4二维数组 做函数的形参 

1.4.1被调用函数形参:

void printArray(int a[3][4],int row);    //形式上: 形参 --数组形式,行数 

void printArray(int (*a)[4],int row);    // 实际上:编译器最终当做指针变量处理;

1.4.2实参:

printArray(a,row);   //   数组名   行数 

1.5二维字符型数组做函数形参:

定义一个二维字符型数组:

char s[3][10] = {"hello","world","china"};

1.5.1被调用函数形参:

void printStr(char s[][10] , int row) //注意需要传行数,因为操作多个字符串

void printStr(char (*s)[10],int row)  //  实际上 :编译器最终当做指针变量处理

1.5.2 实参:

  printStr(s,row);   //数组名 行数

二 .标识符 作用域 和 可见性问题 

1.作用域:

    作用的范围         

    局部变量 --- 一定在某一个{} 范围内          【在函数之内,仅限在{}内使用】

    全局变量  --- 不在任何一个{} 范围内         【在函数之外,若{}内没定义,则用它】

2.可见性:

    程序运行到某个点,哪些标识符可见 ;

3.标识符:

就是你自己定义的一个变量或者函数名之类;

标识符的可见性的规则:

1.先定义,后使用 

2.同一作用域中,不能有同名标识符

3.在不同的作用域,同名标识符,相互之间没有影响 

4.如果是不同的作用域,  但是作用域之间存在嵌套关系则, 内层的作用域的同名标识符,会屏蔽外层的作用域的同名标识符。  (就近原则) 

三,静态变量与动态变量

时间上去区分:

动态变量  :(局部变量---空间是开辟在栈上的---自动申请自动释放)

                     (声明周期):      从定义的语句开始,到所在的作用域范围结束 

静态变量 : (全局变量)

                                             从程序一开始运行,就存在 ,直到程序结束时,销毁 

注意:静态区的变量   只会被初始化一次 (其他文件调用时,不能初始化别的数);且变量的值具有 继承性   ;

1.static 修饰局部变量

        //将局部变量 存储在了 全局区(静态区)

        //将局部变量的生命周期延长 

2. static 修饰全局变量

       //表示 将全局变量 的作用域限定到本文件中 

       //别的文件中不能extern了     

3. static 加在函数前面 

       //  此时效果与修饰全局变量效果一样 

       // 将函数作用域限定到本文件中

4.extern

可以放在函数声明中  --函数声明 

extern int a;    //表示 此时这个a 不是在当前文件中定义的 ,如果要用,请到别的文件中寻找;

     一般使用在多文件编程中:如果想在当前文件使用别的文件中的 全局变量 :extern int a;  相当于,把别的文件中的变量作用域扩展到当前文件;

5.其他

5.1.auto

auto int a;   //   这个是一个自动变量 --- 栈上开辟的变量 

5.2.register

registerint a;   //   建议 存储在  CPU 寄存器    不一定被采纳可能被拒绝;

你可能感兴趣的:(学习)