学习C这么久了,main函数的这三个参数你见过吗?

news2024/11/23 15:23:07

在这里插入图片描述

文章目录

  • 💐专栏导读
  • 💐文章导读
    • 🐧引例1
    • 🐧引例2
  • 🐦认识环境变量
      • 🔔环境变量的概念
      • 🔔常见的环境变量
      • 🔔和环境变量相关的指令
  • 🐦main函数的第三个参数
      • 🔔如何通过代码获取环境变量
        • 🦋方法一 使用参数获取
        • 🦋方法二 使用全局变量获取
        • 🦋方法三 使用系统调用获取(最实用)
      • 🔔环境变量的全局属性
        • 🦋证明
  • 🐦命令行参数
        • 🦋Demo
    • 🔔有什么用?

💐专栏导读

🌸作者简介:花想云 ,在读本科生一枚,C/C++领域新星创作者,新星计划导师,阿里云专家博主,CSDN内容合伙人…致力于 C/C++、Linux 学习。

🌸专栏简介:本文收录于 Linux从入门到精通,本专栏主要内容为本专栏主要内容为Linux的系统性学习,专为小白打造的文章专栏。

🌸相关专栏推荐:C语言初阶系列C语言进阶系列C++系列数据结构与算法

💐文章导读

你知道main函数有几个参数呢?你使用过它们吗?本章我们就一起来认识一下main函数的几个不常见但是作用很大的参数~

在这里插入图片描述

🐧引例1

在Linux中,当我们生成一个可执行程序后一般要使用./ + 文件名的方式运行(./为文件的路径)。我们应该知道例如ls、pwd、touch等这些指令其实都是一个个可执行程序,那么为什么ls在执行的时候不需要用到./呢?

还有ls在执行的时候还可以添加一些参数呢?例如:ls -als -l等。那么我们自己生成的程序能否做到呢?

🐧引例2

在你的印象中,C语言中的main函数有参数吗?有几个参数呢?你是否见过这样的场景:

#include<stdio.h>

int main(int argc,char* argv[],char* envp[])
{
  printf("myprocess\n");
  return 0;
}

如果你见过,那么你清楚这些参数该怎么使用吗?

🐦认识环境变量

🔔环境变量的概念

  • 环境变量(environment variables)一般是指在操作系统中用来指定操作系统运行环境的一些参数;

🔔常见的环境变量

常见的环境变量有这些(我们可以使用$+环境变量名来查看环境变量的值):

  • PATH:指定命令的搜索路径;

在这里插入图片描述

假若我们也想将自己的程序像ls那样不指定路径就可以执行该怎么做呢?使用命令:

$ export PATH=$PATH:文件名

在这里插入图片描述

如上图所示,当我们把可执行程序的路径添加到环境变量PATH中以后,就可以直接使用文件名来执行程序了。

第二种方法

除了上面那种方法我们还可以将可执行程序拷贝到指定目录下(记得要以root的身份):

$ cp -rf 文件名 /usr/bin

在这里插入图片描述

除了PATH以外,还有其它环境变量例如: HOMEPWD等等。

在这里插入图片描述

或者使用指令 env 查看所有的环境变量:

在这里插入图片描述

🔔和环境变量相关的指令

  • echo: 显示某个环境变量值;
  • export: 设置一个新的环境变量;
  • env: 显示所有环境变量;
  • unset: 清除环境变量;
  • set: 显示本地定义的shell变量和环境变量;

🐦main函数的第三个参数

引例中提到了main函数是有参数的,我们首先来看看main函数的第三个参数——envpenvenvironment(环境)的缩写,猜一下它应该和环境变量有些关系。

首先我们可以观察到envp是一个指针数组的类型,它其实是一个表结构,这张表中的内容就是一个个的环境变量。

在这里插入图片描述
环境变量表是一个字符指针数组,每个指针指向一个以’\0’结尾的环境变量字符串。且该表的结尾必须为NULL

🔔如何通过代码获取环境变量

🦋方法一 使用参数获取

第一种方式,我们可以遍历main函数提供的这张环境变量表。代码如下:

#include<stdio.h>

int main(int argc,char* argv[],char* envp[])
{
  for(int i = 0; envp[i]; ++i)
  {
    printf("envp[%d] = %s\n",i,envp[i]);
  }
  return 0;
}

在这里插入图片描述

🦋方法二 使用全局变量获取

除了参数,库还为我们提供了一个全局变量environ。该变量是char**类型,其实就如同envp一样,使用方法也相同。

  • libc中定义的全局变量environ指向环境变量表,environ没有包含在任何头文件中,所以在使用时要用extern声明。
#include<stdio.h>

int main(int argc,char* argv[],char* envp[])
{
  extern char** environ;

  for(int i = 0; environ[i]; ++i)
  {
    printf("environ[%d] = %s\n",i,environ[i]);
  }
 // for(int i = 0; envp[i]; ++i)
 // {
 //   printf("envp[%d] = %s\n",i,envp[i]);
 // }
  return 0;
}

在这里插入图片描述

🦋方法三 使用系统调用获取(最实用)

我们还可以使用系统调用getenv来获取指定的环境变量,这种方法也是最实用的方法。

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

int main(int argc,char* argv[],char* envp[])
{
  char* path = getenv("PATH");
  if(path == NULL)
    perror("getenv");
  else 
    printf("%s\n",path);
    
  return 0;
}

在这里插入图片描述

🔔环境变量的全局属性

  • 环境变量通常具有全局属性,可以被子进程继承下去;

🦋证明

当一个程序变成进程,他的父进程就是bash。那么我们如果将某个环境变量添加到bash的环境变量表里面,该进程能够使用吗?结果如下:

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

int main(int argc,char* argv[],char* envp[])
{
  char* myenv = getenv("HELLO");
  if(myenv == NULL)
    perror("getenv");
  else 
    printf("%s\n",myenv);

  return 0;
}

在这里插入图片描述

🐦命令行参数

认识了main函数中的一个参数。其它两个也就非常容易理解了。在引例中我们提到,为什么ls在执行时可以使用-a、-l等选项,我们平时写的程序怎么不需要呢?

其实main函数为我们提供了这个功能,我们只是平时不太用而已。

🦋Demo

写一个程序测试一下我们能否使用命令行参数:

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

int main(int argc,char* argv[],char* envp[])
{
  for(int i = 0; i < argc; i++)
  {
    printf("argc: %d,argv[%d]=%s\n",argc,i,argv[i]);
  }
  return 0;
}

在这里插入图片描述

🔔有什么用?

我们看到了命令行参数的使用,那么我们平时该怎么使用呢?

我们可以使程序根据不同的命令行参数执行不同的内容从而达到一个程序多种使用的效果。例如:

  • 设计一个计算器,要求可以根据不同的选项完成不同的计算;
#include<stdio.h>
#include<string.h>
#include<stdlib.h>

void Usage(const char* name)
{
  printf("\nUsage:%s -[+][-][*][/]\n\n",name);
  exit(-1);
}
int main(int argc,char* argv[],char* envp[])
{
  if(argc!=2) // 必须指定输入一个参数
    Usage(argv[0]);

  int n1 = 0;
  int n2 = 0;
  int ret = 0;
  printf("-----num1 = ");
  scanf("%d",&n1);
  printf("-----num2 = ");
  scanf("%d",&n2);
  if(strcmp(argv[1],"-+")==0) 
    ret = n1 + n2;
  else if(strcmp(argv[1],"--")==0) 
    ret = n1 - n2;
  else if(strcmp(argv[1],"-*")==0) 
    ret = n1 * n2;
  else if(strcmp(argv[1],"-/")==0) 
    ret = n1 / n2;
  printf("\n-----resault = %d\n",ret);
  return 0;
}

在这里插入图片描述

本章的内容就到这里了,觉得对你有帮助的话就支持一下博主把~

在这里插入图片描述

点击下方个人名片,交流会更方便哦~
↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/540582.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Django SQL注入漏洞复现 (CVE-2022-28347)

漏洞简介 在Django 2.2 的 2.2.28 之前版本、3.2 的 3.2.13 之前版本和 4.0 的 4.0.4 之前版本中的 QuerySet.deexplain() 中发现了SQL注入问题。这是通过传递一个精心编制的字典&#xff08;带有字典扩展&#xff09;作为**options参数来实现的&#xff0c;并将注入负载放置在…

这个插件厉害!Tapdata 格式的 api 也可以导入了

Tapdata 是干嘛的&#xff0c;大家都知道的吧&#xff1f;我简单介绍一下 Tapdata 是自带 ETL 的实时数据服务平台&#xff0c;通过把企业核心数据实时集中到中央化数据平台的方式并通过 API 或者反向同步方式&#xff0c;为下游的交互式应用、微服务或交互式分析提供新鲜实时的…

js逆向-阿里系某688参数sign分析

声明 本文仅供学习参考&#xff0c;如有侵权可私信本人删除&#xff0c;请勿用于其他途径&#xff0c;违者后果自负&#xff01; 如果觉得文章对你有所帮助&#xff0c;可以给博主点击关注和收藏哦&#xff01; 前言 目标网站&#xff1a;aHR0cHM6Ly93d3cuMTY4OC5jb20v 接…

html访问图片资源403问题

问题&#xff1a;图片403 页面不渲染 单独打开图片链接在浏览器却能正常查看 解决办法&#xff1a; 1.数据库中全局下载该字段链接&#xff0c;将图片存到制定文件夹&#xff0c;在系统内调用 2.检查页面head中的是否有此句“<metaname“referrer” content“no-referre…

网络模型及网络编程

名词解释 OSI&#xff08;Open System Interconnect&#xff09;&#xff0c;即开放式系统互联。 一般都叫OSI参考模型&#xff0c;是ISO&#xff08;国际标准化组织&#xff09;组织在1985年研究的网络互连模型。TCP(Transmission Control Protocol)&#xff0c;传送控制协议…

从永远到永远-ElasticSearch

ElasticSearch 1.概述2.入门1.官方地址2.RESTful3.倒排索引4.http请求操作1.索引操作2.document操作1.基本操作2.多条件查询3.区间查询4.完全匹配5.高亮显示6.聚合查询7.映射关系 5.JAVA API1.index操作2.doc操作1.基础操作2.批量操作3.复杂查询 1.概述 结构化数据、非结构化数…

C/C++函数指针和回调函数

一、函数指针 在讲回调函数之前&#xff0c;我们需要了解函数指针。 我们都知道&#xff0c;C语言的灵魂是指针&#xff0c;我们经常使用整型指针&#xff0c;字符串指针&#xff0c;结构体指针等 int *p1; char *p2; STRUCT *p3; //STRUCT为我们定义的结构体但是好像我们一…

springboot+jsp学生平时作业评价系统idea

课程信息管理功能需求主要是对课程信息的管理,包括课程信息的录入、维护、删除&#xff0c;教师可以根据授课计划设定授课进度。学生信息管理功能需求&#xff0c;主要是对学生的基本信息进行管理&#xff0c;教师可以录入学生信息&#xff0c;并可以对学生信息进行维护和删除。…

linux 串口改为固定

在/etc/udev/rules.d 目录下新建定义规则的文件 1. 文件名要按规范写否则改动无效2. 规则文件必须以.rules 结尾3. 规则文件名称必须遵循 xx-name.rules 格式&#xff08;xx 为数字或字母&#xff0c;name 为规则名称&#xff09;&#xff0c;例如 99-serial-ports.rules。4. 规…

PDM入门指南:一文带你了解PDM的基本知识

上一期&#xff0c;我们聊过PLM&#xff1b;这一期&#xff0c;我们接着聊聊PDM。在介绍之前&#xff0c;先回答之前客户提出的问题&#xff1a;上线PLM/PDM后&#xff0c;还需要e企拆图吗&#xff1f;可能需要&#xff0c;原因放在最后&#xff0c;有需要的朋友可直接跳到最后…

Java经典面试题—— 对比 Hashtable、HashMap、TreeMap 有什么不同?

典型回答 Hashtable、HashMap、TreeMap都是最常见的一些Map实现&#xff0c;是以键值对的形式存储和操作数据的容器类型。 Hashtable是早期Java类库提供的一个哈希表实现&#xff0c;本身是同步的&#xff0c;不支持null键和值&#xff0c;由于同步导致的性能开销&#xff0c…

IP 子网划分详解

文章目录 1 概述1.1 划分目的1.2 划分原则1.3 子网掩码 2 IP 子网划分示例3 网工软考真题3.1 判断网络号和主机号3.2 计算可容纳的主机数 1 概述 IP 子网划分&#xff1a;实际上就是设计 子网掩码 的过程。原因&#xff1a;由于在五类的IP地址中&#xff0c;网络号与主机号的的…

【dfs解决分组问题-两道例题——供佬学会!】(A元素是放在已经存在的组别中,还是再创建一个更好?--小孩子才做选择,dfs直接两种情况都试试)

问题关键就是&#xff1a; 一个点&#xff0c;可能 新开一个组 比 放到已经存在的组 更划算 因为后面的数据&#xff0c;我们遍历之前的点时&#xff0c;并不知道 所以我们应该针对每个点&#xff0c;都应该做出一个选择就是 新开一个元组或者放到之前的元组中&#xff0c;都尝…

SolVES 模型生态系统服务功能社会价值评估(基于多源环境QGIS、PostgreSQL、ArcGIS、Maxent、R语言)

查看原文>>>SolVES 模型生态系统服务功能社会价值评估&#xff08;基于多源环境QGIS、PostgreSQL、ArcGIS、Maxent、R语言&#xff09; 目录 第一章、理论基础与研究热点 第二章、SolVES 4.0 模型运行环境配置 第三章、SolVES 4.0 模型运行 第四章、数据获取与入…

简答题题集

简答题&#xff1a; 1.测试和开发如何配合工作&#xff0c;即测试何时介入测试工作&#xff1f; 测试工作应该覆盖需求分析、概要设计、详细设计、编码等前期阶段&#xff0c;而不应该在系统开发初步完成后才开始。 2.软件测试的对象&#xff1a;正确的依据应该是需求规格说明书…

【Java基础篇】数据类型与变量

作者简介&#xff1a; 辭七七&#xff0c;目前大一&#xff0c;正在学习C/C&#xff0c;Java&#xff0c;Python等 作者主页&#xff1a; 七七的个人主页 文章收录专栏&#xff1a;Java.SE&#xff0c;本专栏主要讲解运算符&#xff0c;程序逻辑控制&#xff0c;方法的使用&…

SRC漏洞挖掘

SRC目标搜集 文章类的平台 国内漏洞响应平台&#xff08;SRC&#xff09;导航 - 安全客&#xff0c;安全资讯平台 百度搜索 首先得知道SRC厂商的关键字&#xff0c;利用脚本搜集一波。 比如【应急响应中心】就可以作为一个关键字。通过搜索引擎搜索一波&#xff0c;去重&…

【LeetCode: 343. 整数拆分 | 暴力递归=>记忆化搜索=>动态规划 】

&#x1f680; 算法题 &#x1f680; &#x1f332; 算法刷题专栏 | 面试必备算法 | 面试高频算法 &#x1f340; &#x1f332; 越难的东西,越要努力坚持&#xff0c;因为它具有很高的价值&#xff0c;算法就是这样✨ &#x1f332; 作者简介&#xff1a;硕风和炜&#xff0c;…

前端三剑客

一.前端是什么&#xff1a; 前端主要是考虑怎样能让用户觉得用起来更舒服&#xff0c;考虑界面布局、交互效果、页面加载速度等等&#xff0c;主要是偏向用户看得见的部分&#xff0c;客户端&#xff08;pc、手机、pad&#xff09;上浏览web。网站的“前端”是与用户直接交互的…

自定义表头之数据库设计

数据库设计实现自定义列 表设计如下&#xff1a; 1.数据表 — 就是excel所有列数据的表 字段&#xff1a;&#xff08;这个表根据你所需要的数据列写就可以&#xff09; 案例&#xff1a; 2.列表 — 就是记录每个excel对应的完整列名 字段&#xff1a;&#xff08;我这边是…