【C语言】关于我回头学的那些命令行参数等(七)

简介: 我的第一门语言就是C,但是学艺不精,中途跑去学了C#和Java后,感觉到了C的重要性,毕竟是最接近底层的语言,又跑回来学C。毕竟前两门的控制语句,变量什么的都是类似的,回到C后只需要学习一些特定C的语法,比如宏,预编译指令等等,这些对我来说都是陌生的词汇。所以边学边记录一下以前的知识。

前言


我的第一门语言就是C,但是学艺不精,中途跑去学了C#和Java后,感觉到了C的重要性,毕竟是最接近底层的语言,又跑回来学C。

毕竟前两门的控制语句,变量什么的都是类似的,回到C后只需要学习一些特定C的语法,比如宏,预编译指令等等,这些对我来说都是陌生的词汇。

所以边学边记录一下以前的知识。



一、命令行参数


执行程序时,可以从命令行传值给 C 程序。这些值被称为命令行参数,它们对程序很重要,特别是当您想从外部控制程序,而不是在代码内对这些值进行硬编码时,就显得尤为重要了。

命令行参数是使用 main() 函数参数来处理的。

其中,

argc:传入参数的个数,默认为1(程序名称算一个)

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


因为下述命令的参数只算一个,包括程序自身的名称,所以进入了第一个条件判断。



二、递归


递归指的是在函数的定义中使用函数自身的方法。

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


结果如下:


15 的阶乘为 1307674368000.000000



三、线程


是的,C语言提供了线程支持。C11标准引入了一组线程相关的库函数和头文件,称为“Thread library”。

使用这些函数和头文件,可以在C程序中创建多并发执行的线程来实现异步处理、并行计算等功能。

下面是一个简单的示例代码,用于创建多个线程并在每个线程中运行一个简单的任务:

#include <stdio.h>
#include <threads.h>
int my_thread_func(void* arg)
{
  //1.arg是一个指向void类型的指针,表示不确定类型的数据地址。
  //2.(int*)arg将arg强制转换为指向整型数据的指针
  //这里假设arg所指向的内存储存了一个整型值。
  //3.*(int*)arg表示通过该指针访问其所指向的内存
  //并把其值作为整型数据返回给变量id。
    int id = *(int*)arg;
    printf("Thread %d is running", id);//打印线程ID
    return 0;
}
int main()
{
    const int num_threads = 4;//启动4个线程
    thrd_t threads[num_threads];//在循环中被赋值,保存新建线程的ID号
    int thread_args[num_threads];//参数1,2,3,4
    for (int i = 0; i < num_threads; i++) {
        thread_args[i] = i;
        //创建线程
        thrd_create(&threads[i], my_thread_func, &thread_args[i]);
    }
    for (int i = 0; i < num_threads; i++) {//遍历所有线程ID
        thrd_join(threads[i], NULL);
    }
    return 0;
}


这段程序启动了4个线程,每个线程都执行同一个函数my_thread_func,并把该函数所需的参数传递给线程。

具体解析如下:

1.首先定义了一个常量num_threads,值为4,表示要启动4个线程。

2.创建了两个数组:threadsthread_args。前者存储线程标识符(即线程ID),后者存储传递给线程函数的参数。其中,数组长度都为num_threads

3.进入循环体,遍历数组thread_args中的每一个元素。此时数组内的元素值分别为0、1、2、3。这些值将被传递给4个线程作为参数。

4.在循环体内部,调用了 thrd_create() 函数来创建线程,并将其标识符存储在数组 threads 中。该函数接受三个参数:

第一个参数是指向线程ID的指针,用于保存新建线程的ID号。

第二个参数是指向函数 my_thread_func() 的指针。当新建的线程开始运行时,它将执行这个函数。

第三个参数是指向要传递给新建线程的数据所在内存地址的指针。

5.退出第一个循环体后,进入第二个循环体。遍历数组 threads[], 调用 thrd_join() 函数等待每个线程执行完成。该函数接受两个参数:

第一个参数是线程ID。

第二个参数为指向线程返回值的指针,因为这里用不到,所以传入了 NULL

6.所有线程执行完成后,程序退出并返回0。

最后,使用 thrd_join 函数在主线程中等待所有线程的结束并释放它们的资源。

值得注意的是,C语言标准库只提供了一些基本的线程操作函数和类型,例如创建、销毁、等待和同步线程等。

对于更高级别的功能,例如锁定和互斥、条件变量、信号量等需要使用其他库或实现。

那么C语言总结到这里基本就告一段落了,后面一些更高级的就以后在更新或者自己去学习吧。


目录
相关文章
|
6月前
|
C语言
在C语言中数组作为函数参数的应用与示例
在C语言中数组作为函数参数的应用与示例
67 0
|
6月前
|
C语言
在C语言中多维数组名作为函数参数的应用与示例
在C语言中多维数组名作为函数参数的应用与示例
51 0
|
6月前
|
程序员 编译器 数据处理
C语言与人生函数的对比,使用,参数详解
C语言与人生函数的对比,使用,参数详解
|
12月前
|
C语言
C语言---函数---知识总结(四)---函数的参数
C语言---函数---知识总结(四)---函数的参数
|
存储 C语言
32 C语言 - 命令行参数
32 C语言 - 命令行参数
58 0
|
存储 C语言
7.7.2 【C语言】一维数组名作函数参数
7.7.2 【C语言】一维数组名作函数参数
57 0
|
6月前
|
编译器 C语言
C语言宏定义(#define定义常量​、#define定义宏​、 带有副作用的宏参数、 宏替换的规则、 宏函数的对比)
C语言宏定义(#define定义常量​、#define定义宏​、 带有副作用的宏参数、 宏替换的规则、 宏函数的对比)
|
6月前
|
算法 C语言
C语言函数参数的声明及调用
C语言函数参数的声明及调用
42 1
|
6月前
|
程序员 编译器 C语言
C语言之函数与参数
C语言之函数与参数
45 0
|
C语言
C语言之数组参数,指针参数,函数指针,函数指针数组
C语言之数组参数,指针参数,函数指针,函数指针数组