C语言学习笔记--基础语法四

递归

递归是指在函数的定义中使用函数自身的方法,简言之就是自我调用。

void recursion(){
  recursion();//函数自我调用
}
int main(){
  recursion();
}

Note:使用递归要注意需要有跳出循环的条件,比如阶乘、斐波那契数列等常用到递归。

  • 示例

    阶乘

#include <stdio.h>
double factorial(unsigned int i){
  if(i <= 1){
    return 1;
  }
  return i * factorial(i-1);
}
void main(){
  int i = 15;
  printf("%d 的阶乘为 %f \n",i,factorial(i));
}

Fibonaci斐波那契数列

#include <stdio.h>
int fibonaci(int i){
  if(i==0){
    return 0;
  }
  if(i ==1){
    return 1;
  }
  return fibonaci(i-1)+fibonaci(i-2);
}
void main(){
  int i;
  for(i = 0;i<10;i++){
    printf("%d\t\n",fibonaci(i));
  }
}

可变参数

多数编程语言中都会有可变参数的函数形式

//可变参数,函数内...省略号表示不定个数的参数,在调用时,可以传入数目不定,但是类型总是一致的。
int func(int,...){
  .
  .
  .
}
void main(){
  //调用可变参数的函数,传入参数的个数可以是不同的
  func(1,2,3);
  func(1,2,3,4);
}

注:使用可变参数函数,需要导入stdarg.h头文件,其中定义了相关的宏和函数步骤:

  • 定义一个可变参数函数,最后一个参数为...省略号,前面一个参数总是int表示参数的个数
  • 函数中创建一个va_list类型变量,该类型定义在stdarg.h
  • 使用int参数和va_start宏来初始化va_list变量为一个参数列表
  • 使用va_arg宏和va_list变量来访问参数列表中的每个项
  • 使用va_end来清理赋予va_list变量的内存

示例:

#include <stdio.h>
#include <stdarg.h>
//定义一个求平均数的函数,传入的参数不定个数
double average(int num,...){
  va_list valist;
  double sum = 0.0;
  int i;
  //为 num 个参数初始化 valist
  va_start(valist,num);
  //访问所有赋值给valist的参数
  for(i=0; i<num;i++){
    sum+=va_arg(valist,int);
  }
  //清理为 valist 保留的内存
  va_end(valist);
  return sum/num;
}
int main(){
  printf("Average of 2,3,4,5 = %f \n",average(4,2,3,4,5));
  printf("Average of 5,10,15 = %f \n",average(3,5,10,15));
}

内存管理

C语言为内存的分配和管理提供了几个函数stdlib.h文件中

#include <stdio.h>
#include <stdlib.h>
//该函数分配一个带有 num 个元素的数组,每个元素大小 size
void *calloc(int num,int size);
//该函数释放 address 所指向的内存块
void fress(void *address);
//该函数分配一个 num 个字节的数组,并初始化
void *malloc(int num);
//该函数重新分配内存,把内存扩展到newsize
void *realloc(void *address,int newsize);

编程时,若预先知道数组大小,便容易定义char name[100]若不确定数组大小,则可以用指针来指向未定义所需内存大小的字符,后期动态分配内存。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(){
  //已知大小的定义方式
  char name[100];
  //不确定大小,使用指针作
  char *description;

  strcpy(name,"Hello C");
  //动态分配内存
  description = malloc(200 * sizeof(char));
  //也可以用calloc()函数替代malloc()
  if(description == NULL){
    fprintf(stderr,"Error,不能分配所需内存\n");
  }else{
    strcpy(description,"Hello C ,非常不错的编程语言\n");
  }
  printf("Name = %s \n",name);
  printf("Description:%s \n",description);
}

程序退出时,会自动释放内存,但是依然建议在不需要内存时候,手动调用free()函数释放内存。也可以通过realloc()调整内存大小

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(){
  char name[100];
  char *description;
  strcpy(name,"Boby");
  //动态分配内存
  description = calloc(30,sizeof(char));
  if(description == NULL){
    fprintf(stderr,"错了,又没有分配好内存\n");
  }else {
    strcpy(description,"Boby,你好啊\n");
  }
  //重新调整内存大小
  description = realloc(description,100*sizeof(char));
  if(description == NULL){
    fprintf(stderr,"好吧,又错了,内存没有调整正确\n";)
  }else{
    strcat(description,"Boby,你在哪儿啊\n");  
  }
  printf("Name = %s \n",name);
  printf("description : %s \n",description);
  //释放内存
  free(description);
}

命令行参数

执行程序时,可以从命令行传值给C程序,这类值称为命令行参数,当其需要从外部控制程序时候,这类参数就很重要了。

命令行参数,是使用main()函数参数来处理,其中argc是传入参数的个数,argv[]是一个指针数组,指向传递给程序的每个参数。

#include <stdio.h>
int main(int argc,char *argv[]){
  if(argc == 2){
    printf("传递来的参数是%s\n",argv[1]);
  }else if(argc > 2){
    printf("传递来了许多参数\n");
  }else{
    printf("只有一个参数\n");
  }
}

Note:需要说明的是argv[0]存储程序的名字,argv[1]才是第一个参数的指针,*argv[n]是最后一个参数,如果没有任何参数,argc就是1,传递一个参数,argc就是2;

多个命令行参数之间用空格分隔,多是参数本身带有空格,那就放在""''之内

$ gcc test.c
$ ./test.out argument1,argument2
$ ./test.out argument1,"argument with blank"
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值