C语言学习第7天(错误处理、递归、内存管理)默认熟悉数据结构和java基础

重点强调一下 初学者可以去https://www.runoob.com/网站学习各种语言的基础

错误处理

C语言不提供对错误处理的直接支持,但它可以用返回值的形式允许你访问底层数据。在发生错误的时候,大多数的C或者UNIX函数调用返回1或者NULL,同时设置一个错误代码errno,该错误代码是全局变量,表示在函数调用期间发生了错误。我们可以在errno.h头文件中找到各种各样的错误代码。

总结一下:

我们可以通过检查返回值来决定采用那些适当的方法去处理。
程序员一般在程序初始化的时候把errno设置为0,这是一种编程习惯。0表示程序中没有错误。

错误函数

C中的一般使用perror()函数、strerror()函数提供与errno相关的文本消息

  1. perror() 函数显示您传给它的字符串,后跟一个冒号、一个空格和当前 errno 值的文本表示形式。
  2. strerror() 函数,返回一个指针,指针指向当前 errno 值的文本表示形式。
  3. 除数为0的错误
  4. 程序退出状态(程序执行完成退出带有值EXIT_SUCCESS,EXIT_SUCCESS是宏,定义为0。程序执行过程中也有一种错误状态,当退出时出现EXIT_FAILURE,定义为-1。)

C语言中的stdin,stdout, stderr

stdin 表示输入流,指键盘键入。
stdout 和 stderr 是输出,默认为显示器输出stderr是没有缓冲的,立即输出;stdout默认是缓冲的,遇到’\n’才输出。

C语言的printf()函数、fprintf()函数、perror()函数

这三个函数都是输出函数。
printf()函数是向stdout中输出。printf() == fprintf(stdout, ‘’****")。printf()函数是最常用的

fprintf()函数输出到屏幕上。方式有两种,fprintf(stdout, ‘’*")或者 fprintf(stderr, "")

perror()是向stderr中输出。 perror() == fprintf(stderr, “***”)

递归

递归在数学上的经典例子:斐波那契数列和数的阶乘
举例如下:
从前有座山,山里有座庙,庙里有个老和尚,正在给小和尚讲故事呢!故事是什么呢?"从前有座山,山里有座庙,庙里有个老和尚,正在给小和尚讲故事呢!故事是什么呢?‘从前有座山,山里有座庙,庙里有个老和尚,正在给小和尚讲故事呢!故事是什么呢?……’"

C语言是支持递归的,但是要注意递归终止条件。否则会陷入死循环。

可变参数

我的理解:当我们使用一个函数的时候,由于输入的参数过多,或者不知道输入几个参数,所以希望输入参数的数量是可变的。
例如:

int func(int, ... ) 
{
}

函数 func() 最后一个参数写成省略号,即三个点号(…),省略号之前的那个参数是 int,代表了要传递的可变参数的总数。为了使用这个功能,您需要使用 stdarg.h 头文件,该文件提供了实现可变参数功能的函数和宏。具体步骤如下:

  1. 定义一个函数,最后一个参数为省略号,省略号前面可以设置自定义参数
  2. 在函数定义中创建一个 va_list 类型变量,该类型是在 stdarg.h 头文件中定义的。
  3. 使用 int 参数和 va_start 宏来初始化 va_list 变量为一个参数列表。宏 va_start 是在 stdarg.h 头文件中定义的。
  4. 使用 va_arg 宏和 va_list 变量来访问参数列表中的每个项。
  5. 使用宏 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));
}

输出结果:

Average of 2, 3, 4, 5 = 3.500000
Average of 5, 10, 15 = 10.000000

内存管理

C语言的内存分配管理函数

  1. void calloc(int num, int size);在内存中动态地分配 num 个长度为 size 的连续空间,并将每一个字节都初始化为 0。所以它的结果是分配了 numsize 个字节长度的内存空间,并且每个字节的值都是0。
  2. void free(void *address); 该函数释放 address 所指向的内存块,释放的是动态分配的内存空间。
  3. void *malloc(int num); 在堆区分配一块指定大小的内存空间,用来存放数据。这块内存空间在函数执行完成后不会被初始化,它们的值是未知的。
    4.void *realloc(void *address, int newsize); 该函数重新分配内存,把内存扩展到 newsize。

动态内存分配

如果实现不知道要分配存储空间的大小
例如您想存储有关一个主题的详细描述。在这里,我们需要定义一个指针,该指针指向未定义所需内存大小的字符,后续再根据需求来分配内存,如下所示:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
int main()
{
   char name[100];
   char *description;
 
   strcpy(name, "Zara Ali");
 
   /* 动态分配内存 */
   description = (char *)malloc( 200 * sizeof(char) );
   if( description == NULL )
   {
      fprintf(stderr, "Error - unable to allocate required memory\n");
   }
   else
   {
      strcpy( description, "Zara ali a DPS student in class 10th");
   }
   printf("Name = %s\n", name );
   printf("Description: %s\n", description );
}

命令行参数

执行程序的时候,可以从命令行传值给C程序。可以帮助我们从外部控制程序。
命令行参数使用main()函数来处理,其中,argc指传入的这个参数,argv[] 是一个指针数组,指向传递给程序的每个参数。

#include <stdio.h>

int main( int argc, char *argv[] )  
{
   if( argc == 2 )
   {
      printf("The argument supplied is %s\n", argv[1]);
   }
   else if( argc > 2 )
   {
      printf("Too many arguments supplied.\n");
   }
   else
   {
      printf("One argument expected.\n");
   }
}

使用一个参数,编译并执行上面的代码,它会产生下列结果:
$./a.out testing
The argument supplied is testing
使用两个参数,编译并执行上面的代码,它会产生下列结果:
$./a.out testing1 testing2
Too many arguments supplied.
不传任何参数,编译并执行上面的代码,它会产生下列结果:
$./a.out
One argument expected

应当指出的是,argv[0] 存储程序的名称,argv[1] 是一个指向第一个命令行参数的指针,*argv[n] 是最后一个参数。如果没有提供任何参数,argc 将为 1,否则,如果传递了一个参数,argc 将被设置为 2。

多个命令行参数之间用空格分隔,但是如果参数本身带有空格,那么传递参数的时候应把参数放置在双引号 “” 或单引号 ‘’ 内部。让我们重新编写上面的实例,有一个空间,那么你可以通过这样的观点,把它们放在双引号或单引号""""。让我们重新编写上面的实例,向程序传递一个放置在双引号内部的命令行参数:

#include <stdio.h>

int main( int argc, char *argv[] )  
{
   printf("Program name %s\n", argv[0]);
 
   if( argc == 2 )
   {
      printf("The argument supplied is %s\n", argv[1]);
   }
   else if( argc > 2 )
   {
      printf("Too many arguments supplied.\n");
   }
   else
   {
      printf("One argument expected.\n");
   }
}
使用一个用空格分隔的简单参数,参数括在双引号中,编译并执行上面的代码,它会产生下列结果:
$./a.out "testing1 testing2"

Progranm name ./a.out
The argument supplied is testing1 testing2
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值