C语言知识扫盲

news2024/11/24 19:53:17

文章目录

    • 1,各种类型所占字节数
    • 2,main函数是可以传入参数的
    • 3,C语言中extern的用法
    • 4,gettop()函数
    • 5,C/C++中枚举类型enum使用

1,各种类型所占字节数

类型16位32位64位
char111
short int222
int244
unsigned int244
float444
double888
long448
long long888
unsigned long448

2,main函数是可以传入参数的

首先说明的是,可能有些人认为main函数是不可传入参数的,但是实际上这是错误的。main函数可以从命令行获取参数,从而提高代码的复用性。
什么时候使用带参数的主函数?

我们需要和程序进行交互。你知道,在程序运行过程中,可以通过scanf函数,输入数组、字符、字符串给程序处理。那么能不能在程序启动的时候(),就携带参数给他,而不是运行过程中敲入东西给程序。这时候需要用用到带参数(int argc, char argv[])的main函数。
为main函数传参时,可选的main函数原形为int main(int argc,char*argv[],char*envp[])
①、第一个参数argc表示的是传入参数的个数
②、第二个参数char
argv[],是字符串数组,用来存放指向的字符串参数的指针数组,每一个元素指向一个参数。各成员含义如下:
   argv[0]:指向程序运行的全路径名
   argv[1]:指向执行程序名后的第一个字符串 ,表示真正传入的第一个参数
   argv[2]:指向执行程序名后的第二个字符串 ,表示传入的第二个参数
   ……
   argv[n]:指向执行程序名后的第n个字符串 ,表示传入的第n个参数
 规定:argv[argc]为NULL ,表示参数的结尾。
 
③、第三个参数char* envp[],也是一个字符串数组,主要是保存这用户环境中的变量字符串,以NULL结束。

3,C语言中extern的用法

  1. extern修饰变量的声明。
    举例来说,如果文件a.c需要引用b.c中变量int v,就可以在a.c中声明extern int v,然后就可以引用变量v。能够被其他模块以extern修饰符引用到的变量通常是全局变量。还有很重要的一点是,extern int v可以放在a.c中的任何地方,比如你可以在a.c中的函数fun定义的开头处声明extern int v,然后就可以引用到变量v了,只不过这样只能在函数fun作用域中引用v罢了,这还是变量作用域的问题。对于这一点来说,很多人使用的时候都心存顾虑。好像extern声明只能用于文件作用域似的。

  2. extern修饰函数声明。从本质上来讲,变量和函数没有区别。函数名是指向函数二进制块开头处的指针。如果文件a.c需要引用b.c中的函数,比如在b.c中原型是int fun(int mu),那么就可以在a.c中声明extern int fun(int mu),然后就能使用fun来做任何事情。就像变量的声明一样,extern int fun(int mu)可以放在a.c中任何地方,而不一定非要放在a.c的文件作用域的范围中。对其他模块中函数的引用,最常用的方法是包含这些函数声明的头文件。
    使用extern和包含头文件来引用函数有什么区别呢?extern的引用方式比包含头文件要简洁得多!extern的使用方法是直接了当的,想引用哪个函数就用extern声明哪个函数。这大概是KISS原则的一种体现吧!这样做的一个明显的好处是,会加速程序的编译(确切的说是预处理)的过程,节省时间。在大型C程序编译过程中,这种差异是非常明显的。

  3. 此外,extern修饰符可用于指示C或者C++函数的调用规范。

比如在C++中调用C库函数,就需要在C++程序中用extern “C”声明要引用的函数。这是给链接器用的,告诉链接器在链接的时候用C函数规范来链接。主要原因是C++和C程序编译完成后在目标代码中命名规则不同。

  1. 举个简单的例子:
    用C语言编写程序的时候,我们经常会遇到这样一种情况:希望在头文件中定义一个全局变量,然后包含到两个不同的c文件中,希望这个全局变量能在两个文件中共用。

举例说明:项目文件夹project下有main.c、common.c和common.h三个文件,其中
common.h文件分别#include在main.c和common.c文件中。现在希望声明一个字符型变量key,在main.c和common.c中公用。

有人想,既然是想两个文件都用,那就在common.h中声明一个unsigned char key,然后由于包含关系,在main.c和common.c中都是可见的,所以就能共用了。

这种想法其实是很多初学者都会想到的,想起来确实有道理,但是实际写出来,我们发现编译的时候编译器提示出错,一般提示大概都类似于:Error: L6200E: Symbol key multiply defined (by common.o and main.o). 也就是说编译器认为我们重复定义了key这个变量。这是因为#include命令就是原封不同的把头文件中的内容搬到#include的位置,所以相当于main.c和common.c中都执行了一次unsigned char key,而C语言中全局变量是项目内(或者叫工程内)可见的,这样就造成了一个项目中两个变量key,编译器就认为是重复定义。

正确的解决办法:使用extern关键字来声明变量为外部变量。具体说就是在其中一个c文件中定义一个全局变量key,然后在另一个要使用key这个变量的c文件中使用extern关键字声明一次,说明这个变量为外部变量,是在其他的c文件中定义的全局变量。请注意我这里的用词:定义和声明。例如在main.c文件中定义变量key,在common.c文件中声明key变量为外部变量,这样这两个文件中就能共享这个变量key了。
原创作者;https://blog.csdn.net/gao1440156051/article/details/48035911

4,gettop()函数

int getopt(int argc, char * const argv[], const char *optstring);
 
extern char *optarg;
extern int optind, opterr, optopt;

getopt 参数说明:

argc:通常由 main 函数直接传入,表示参数的数量
argv:通常也由 main 函数直接传入,表示参数的字符串变量数组
optstring:一个包含正确的参数选项字符串,用于参数的解析。例如 “abc:”,其中 -a,-b 就表示两个普通选项,-c 表示一个必须有参数的选项(此时参数和-c之间的空格可有可无),因为它后面有一个冒号,"abc::"则表示-c之后可跟参数也可以不用跟参数(此时 选项 -c 后面跟参数的时候,一定不能有空格)

外部变量说明:

optarg:如果某个选项有参数,这包含当前选项的参数字符串
optind:argv 的当前索引值
opterr:正常运行状态下为 0。非零时表示存在无效选项或者缺少选项参数,并输出其错误信息
optopt:当发现无效选项字符时,即 getopt() 方法返回 ? 字符,optopt 中包含的就是发现的无效选项字符;

用一个例子说明:

#include <stdio.h>
#include <unistd.h>
 
int main(int argc, char *argv[]) {
    int o;
    const char *optstring = "abc:"; // 有三个选项-abc,其中c选项后有冒号,所以后面必须有参数
    while ((o = getopt(argc, argv, optstring)) != -1) {
        switch (o) {
            case 'a':
                printf("opt is a, oprarg is: %s\n", optarg);
                break;
            case 'b':
                printf("opt is b, oprarg is: %s\n", optarg);
                break;
            case 'c':
                printf("opt is c, oprarg is: %s\n", optarg);
                break;
            case '?':
                printf("error optopt: %c\n", optopt);
                printf("error opterr: %d\n", opterr);
                break;
        }
    }
    return 0;
}

在这里插入图片描述
分析:

命令 gcc OptDemo.c -o OptDemo 是使用 gcc 把 OptDemo.c 编译成可执行程序,命名为 OptDemo

第一次运行 ./OptDemo -a -b -c afei 正常执行和输出

第二次运行 ./OptDemo -abc 由于选项 c 后没有输入参数,于是报错

第三次运行 ./OptDemo -d 由于选项 d 不是我们在 optstring 中预定义的选项,于是报错
原文链接:https://blog.csdn.net/afei__/article/details/81261879

5,C/C++中枚举类型enum使用

1. 说明:
  枚举enum的出现,主要是为了解决一些特定属性的赋值,变量取值仅在一定有限范围内的问题。例如一年只有十二个月取值,一个星期只有七天情况,人的性别只有男女两种等。这些属性如果简简单单用int类型变量定义就有失妥当,能取的值远远超出可取值范围。所以我们希望给这些属性变量,定义一个有限取值范围。
  枚举即将变量的值一一列举出来,变量只限于列举出来的值的范围内取值。

2. 定义
  语法结构:
  enum [枚举名] {e1[=Value1], e2[=Value2] ,… …};
e1、e2… …:称为枚举常量,枚举成员,也称为枚举子。
  Value1,Value2… …:称为枚举子值,即枚举值,可忽略不写,默认从0依次赋值。
  例如:

enum color {red,green,blue}; //枚举值分别为0,1,2.

定义枚举类型变量:
  [enum] 枚举名 枚举变量名 [=初始化值];
  例如:

color paint = red;
enum color paint = red; 
enum color {red=1 , green =5, blue=10} paint;

3. 枚举语法
  ①.枚举成员不是变量,而是常数,和const定义常变量一样,所以不能对枚举元素进行赋值。
  ②.枚举成员作为常量,定义的时候存储的值按列举顺序依次默认为0,1,2……。当然,声明时候可以修改其存储值,即修改枚举值,但不可以为负数,如-1,-2等,且枚举值为整数。
  例如:

enum color {red, green=10,blue}; //依次为0,10,11

这种情况下,red枚举值依旧默认为0,green则为10,而blue没有赋值,则随上个枚举值递增下去,所以为11。
  枚举值在未特定赋值外,后续枚举成员默认都是依上个成员的枚举值依次递增的。  
  ③. 枚举成员不是简单字符串常量,使用的时候无需添加单、双引号。
  ④.枚举成员不可以重复,但是枚举值可以重复
。重复枚举值的枚举成员表明它们具有共同性质,所以放在一起。
  例如:

enum weeks {mon=1,tue=1,wed=1,thu=1,fri=1,sat=2,sun=2};

一周周一到周五是工作日,我们希望它们具有共性和相同的枚举值。而周末休息,我们希望它两有另外一个枚举值。
  ⑤.一个整数不能直接赋给一个枚举变量,必须强制进行类型转换才能赋值。
  
  例如:

enum weeks day;
day =(weeks)2;

⑥.枚举值可以用在if-else或者switch-case判断中。
 
  例如:

if(day != mon)
{
    printf("今天是工作日\n");
}

⑦.**编译平台输出枚举类型变量,输出的不是枚举常量名称,而是枚举值。**就像const int n=1输出的并不是’n’这个字符,而是1这个值。
 
  例如:

enum weeks day = mon; //定义枚举weeks类型变量并初始化
day = (weeks)2;  
cout<<day<<endl;      //输出结果为2,并不是"sat"字符串常量      

4. 枚举应用程序

当输入今天星期几(1-7),我们希望判断今天是否上班(公司规定周一到周五工作,周末休息)。

#include<stdio.h> 

int main( ) 
{ 

    enum weekday {sun=1,mon,tue,wed,thu,fri,sat} day; //从1开始
    int k; 
    printf("请输入今天星期几(1--7):"); 
    scanf("%d",&k); 
    day=(enum weekday)k; 
    switch(day) 
    {        
        case mon:  
        case tue:
        case wed:  
        case thu:  
        case fri:       printf("今天上班\n"); break; 

        case sun:
        case sat:       printf("今天休息\n"); break; 

        default:        printf("输入有误\n"); break; 
    } 
    return 0;
}

原文链接:https://blog.csdn.net/fx677588/article/details/52679803

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

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

相关文章

QUIC协议原理分析

Quic 相比现在广泛应用的 http2tcptls 协议有如下优势 [2]&#xff1a; 减少了 TCP 三次握手及 TLS 握手时间。改进的拥塞控制。避免队头阻塞的多路复用。连接迁移。前向冗余纠错。 队头阻塞 队头阻塞主要是 TCP 协议的可靠性机制引入的。TCP 使用序列号来标识数据的顺序&am…

学C的第二十七天【指针的进阶(三)】

相关代码gitee自取&#xff1a;C语言学习日记: 加油努力 (gitee.com) 接上期&#xff1a; 学C的第二十六天【指针的进阶&#xff08;二&#xff09;】_高高的胖子的博客-CSDN博客 复习巩固&#xff1a; 数组名&#xff1a; 数组名是数组首元素的地址&#xff0c; 但是有两个…

数据结构与算法:10种常见算法

前言 本文主要讲解10种常见算法 数据结构与算法文章列表 数据结构与算法文章列表: 点击此处跳转查看 目录 1 二分查找算法 二分查找&#xff08;Binary Search&#xff09;是一种在有序数组中查找目标值的常用算法。它通过将目标值与数组中间元素进行比较&#xff0c;可以快…

Cesium被接入数字孪生系统后会产生怎样的改变?

众所周知&#xff0c;Cesium凭借其开源免费的特点一直垄断着整个三维GIS的生态系统&#xff0c;但是随着数字孪生技术的发展以及各项新需求的不断涌现&#xff0c;Cesium与数字孪生系统相结合的潜力也逐渐凸显。 一般而言&#xff0c;Cesium如果想要升级视效就需要去用CesiumF…

基于springboot的智慧养老系统

博主主页&#xff1a;猫头鹰源码 博主简介&#xff1a;Java领域优质创作者、CSDN博客专家、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战 主要内容&#xff1a;毕业设计(Javaweb项目|小程序等)、简历模板、学习资料、面试题库、技术咨询 文末联系获取 项目介绍…

常用的前端可视化Web组态工具

前言 随着创新技术驱动工业物联网不断发展&#xff0c;设备联网所产生的多样化数据&#xff0c;在边缘端与云端进行大数据分析&#xff0c;成为工业应用场景数字化的需求。跨系统可通用&#xff0c;不受硬件限制达成无缝整合&#xff0c;监控组态软件SCADA成为物联网时代建构出…

Unity游戏源码分享-Unity手游火柴忍者游戏StickmanDojo

Unity游戏源码分享-Unity手游火柴忍者游戏StickmanDojo 项目地址&#xff1a;https://download.csdn.net/download/Highning0007/88050234

Windows bat隐藏运行窗口的几种方案

文章目录 一、背景二、测试数据三、隐藏bat运行窗口方案1. 使用VBScript脚本2. 使用mshta调用js或vbs脚本3. 将bat编译为exe程序4. 使用任务计划程序 一、背景 有些程序在执行批处理脚本时&#xff0c;可能会看到dos窗口&#xff0c;或者看到窗口一闪而过。如果批处理脚本执行…

Layui基本功能(增删改查)

话不多说&#xff0c;根据我前面的博客我们直接进行操作。记住以下的文件放置&#xff0c;防止操作出不来. 这是我们要完成的界面及功能 后台功能实现 数据查看 我们在userDao方法里面进行增删改查的方法我们在userAction进行方法的编写R工具类的介绍 查询 userDao方法 因为我…

使用亚马逊(AWS)云服务在S3上实现图片缩放功能(CloudFront/S3[AccessPoint/LambdaAccessPoint])

亚马逊云服务中的S3对象存储功能和国内阿里云的oss对象存储使用基本一致。但是涉及到存储内容处理时&#xff0c;两家有些差别。 比如&#xff1a;对于云存储中的图片资源&#xff0c;阿里云比较人性化对于基本的缩放裁剪功能已经帮我们封装好了&#xff0c;只需要在url地址后…

window环境下安装Node并修改保存缓存的位置

0, 卸载Node 打开cmd命令行窗口 输入&#xff1a; npm cache clean --force然后在控制面版中卸载node 1&#xff0c;官网下载Node.js 点击官网下载 如一台电脑需要多个node环境 可使用nvm命令进行操作安装并且可以切换 2&#xff0c; 配置环境变量 安装成功之后&#x…

竹云参编 |《数据经纪从业人员评价规范》团体标准在2023全球数字经济大会发布

经国务院批准&#xff0c;由北京市人民政府、国家发展和改革委员会、工业和信息化部、商务部、国家互联网信息办公室、中国科学技术协会共同主办的2023全球数字经济大会在中国北京国家会议中心隆重召开。 深圳竹云科技股份有限公司作为主要编制单位&#xff0c;联合深圳数据交…

新大陆物联网云平台-物联网云平台推荐-免费好用的物联网平台

一、前言 作为多年的物联网开发者&#xff0c;使用过很多付费的物联网云平台&#xff0c;包括阿里云、华为云等&#xff0c;也使用过很多免费开源的物联网云平台&#xff0c;但就操作来说&#xff0c;我认为最便利的还是新大陆物联网云平台&#xff08;NLECloud - 新大陆物联网…

【Elasticsearch】DSL查询文档

目录 1.DSL查询文档 1.1.DSL查询分类 1.2.全文检索查询 1.2.1.使用场景 1.2.2.基本语法 1.2.3.示例 1.2.4.总结 1.3.精准查询 1.3.1.term查询 1.3.2.range查询 1.3.3.总结 1.4.地理坐标查询 1.4.1.矩形范围查询 1.4.2.附近查询 1.5.复合查询 1.5.1.相关性算分 …

vagrant和vitrulBox创建虚拟机后使用xshell连接

1. 先在cmd使用vagrant ssh连接主机, 修改系统配置,允许密码登录 vi /etc/ssh/sshd_config PasswordAuthentication no 将这行的no改成yes 2. 重启ssh service sshd restart 3.打开ssh,输入主机ip 端口22 账号root 密码默认为 vagrant

解决 param image not exist 与 image format error(百度 AI)

前言 注意&#xff0c;此文的 AI&#xff0c;是指识别图文、人脸的 AI 功能&#xff0c;而不是文心一言那种对话形 AI。 最近在尝试使用百度 AI 功能&#xff0c;很有趣是不假了&#xff0c;但也有很多坑&#xff0c;特此记录一下。 正文 后文以使用 通用物体和场景识别 功能…

Linux之磁盘管理

说一下linux中磁盘分区问题 首先每一个分区都是独立的 &#xff0c;基本上来说都是可以独立分配空间的 但是一般如下目录是自动放到根目录下面的 如果根分区用完了&#xff0c;/home下面的分区空间还能用吗&#xff0c;对系统有什么影响 文件类型 给linux虚拟机扩展分区 备注&…

简爱思维导图怎么画?几个超实用绘制步骤赶紧get

简爱思维导图怎么画&#xff1f;思维导图是一种有效的信息组织和表达工具&#xff0c;能够帮助我们更好地整理思路、提高学习效率。下面这篇文章就带大家了解一下简爱思维导图的绘制步骤&#xff0c;并分享4个超实用步骤&#xff0c;助你快速掌握。 在绘制思维导图之前&#xf…

Linux中常用的监控性能的命令(sar、mpstat,vmstat, iostat,)详解

Linux中常用的监控性能的命令有&#xff1a; sar&#xff1a;能查看CPU的平均信息&#xff0c;还能查看指定CPU的信息。与mpstat相比&#xff0c;sar能查看CPU历史信息 mpstat&#xff1a;能查看所有CPU的平均信息&#xff0c;还能查看指定CPU的信息。 与sar相比&#xff0c…

解密横幅banner图的制作秘籍:一文帮你解答所有疑问

Banner是网站首页的关键元素之一。访问者进入网站后&#xff0c;一般首先看到的是Banner图。Banner图会很大程度上影响访问者对网站的第一印象&#xff0c;以及网站对访问者的吸引力。 如果banner图设计得很好&#xff0c;访问者会有兴趣继续阅读。如果Banner图设计得不好&…