C语言要点细细梳理(上)

1.类型转换

1.1 隐式类型转换

在两个不同类型数据进行运算时,会把低精度类型的数据转为与高精度类型一致的数据类型然后计算,然后再根据赋值的需要把计算结果转回去

1.2 强制类型转换

可以将某种类型的数据转换为想要的精度,一般int、double、float可以相互转,但是可能会损失精度。

  • 注意,如果想要将字符串强制转为int类型将会报编译错误

2. 输入输出控制

2.1 输出控制:printf

格式控制符%d的数量可以不与需要输出的字符数量对应,不会报错,但是会造成输出与预期不符的情况。
如果没有格式控制符,只有想要输出的变量,将会报编译错误

2.2 输入控制:scanf

输入存入的数据需要提供该数据的地址,形如&a(变量a的地址)
有两种典型的错误:

  • 未提供地址:如下所示,将会报编译错误
scanf("%d",a);
  • 提供地址数少于输入:如下所示,将会报运行时错误
scanf("%d %d",&a);//输入两个数据

2.3 输出格式控制(C风格)

指定解读方式

  • %d: 解读为有符号十进制(decimal)整数
  • %f:解读为单精度浮点数(float)
  • %u:解读为无符号(unsigned)十进制整数
  • %c:解读为单个字符(character)

例子:

int a =65;
printf("%d %c %f",a,a,a);
//输出结果为:65 A 0.000000

指定数据格式

控制宽度
  • %md:指定输出宽度为m,默认右对齐,如果不足则补空格
    在这里插入图片描述
控制小数位数
  • %.mf:指定暴力小数点后m位,四舍五入
    在这里插入图片描述
同时控制宽度和小数位数
  • %n.mf:指定宽度为n(默认右对齐),并且保留小数点后m位,注意小数点也占一个宽度,不足宽补空格
    在这里插入图片描述
指定输出整数的进制
  • %0x:将数据理解为整数,并且输出16进制表示,注意是零和x(x小写则16进制字母小写)(X大写则16进制字符大写)

在这里插入图片描述

使用指定字符控制宽度
  • %0md:指定整数宽度为m,宽度不足用0补齐
    在这里插入图片描述
需要输出%

连续使用两个%,前一个%作为转义符号

输入格式控制
scanf("Please input:%d",&a);
  • 上述代码指明了程序期望的用户输入格式
  • 如果用户按照Please input:1的格式输入,则可以正常运行
  • 如果直接输入1,不会报错,但是读取的输入会与预期不符合
一些例子

在这里插入图片描述

3.宏定义与不变量

3.1 宏(文本批量替换功能)

  • 在编程领域,“宏”就是指通过预设,对指定的文本内容进行替换
  • c语言中,通过#define预编译指令定义一个宏
  • 如下宏定义代码,在预编译阶段(即编译前),把源码中所有的PI改成对应的数字
#define PI 3.141592679545215498795461648794856213245978945123126748974653126857984653268757712954728768654554
  • 宏定义不止可以定义常量,也可以带参数定义:
    在这里插入图片描述
  • 需要注意宏定义是简单机械的替换,注意下面这个例子,为了避免这样的问题,可以在宏定义时对计算的值加上括号
    在这里插入图片描述

3.2 不变量

  • 不变量是加限制的变量,即不可通过赋值符号进行改变(i.e. 不可作为等号左值),在普通变量定义前加上const即可定义为不变量(注意是加在最前面)
  • 注意,试图通过等号为不变量赋值,将会报编译错误
  • 事实上,不变量只是限定为不能通过赋值符号赋值,不可以作为左值,但是可以作为右值参与运算,如果需要修改值,可以通过指针+间接引用改变绕过限制,但是不建议这么做

常见的错误理解:(A、B、D会编译错误,C绕过限制不报错,但是不推荐这样做)
在这里插入图片描述

3.3 宏定义与不变量辨析

  • 宏定义是预编译指令,本质是文本的替换,支持复杂的带参数的文本模式替换
  • 不变量是语句,本质是对变量的修饰,限定其不能通过赋值号赋值
#define定义的常量和const限定的不变量的区别

在这里插入图片描述

4.技术知识

4.1 转义字符

  • ‘\n’、‘\0’、‘\t’、‘’‘、’"‘、’\'等使用反斜杠

4.2 “溢出”

  • 例如unsigned int加到最大值,再加一会溢出,显示出来的值是0
  • 溢出其实是,最大值再加1回到最小值,最小值再减1回到最大值

4.3 小数

  • 整数除法的本质是做隐式类型转换:int=>float=>int
  • float=>int的类型转换是截除小数的,会损失精度,不会进行四舍五入
  • printf使用的格式控制用于指定对数据的理解和呈现方式,不是类型转换
  • %.mf指将数据理解为浮点数,并且呈现m为,涉及对数据的理解,会进行四舍五入

5. 函数

5.1 函数定义——做饼

明确函数 :

  1. 接收的参数
  2. 返回值类型
  3. 具体操作

函数的定义主要包括:指明返回值、明确参数列表、编写函数逻辑三部分

5.2 函数声明——画饼

明确函数:

  1. 接收的参数
  2. 返回值的类型

函数定义是函数的实际执行部分(工人师傅),函数声明就是明确接收什么返回什么(名片),不涉及细节

5.3 函数调用与传参

调用时找到声明即可。

  • 如果调用时看不到声明,则报编译错误
  • 如果找到声明找不到定义,则报链接错误
    在这里插入图片描述

5.4 函数返回值

  • 无论再函数内部何处,return语句的执行将立即结束函数并提交返回值
  • 函数结束后,再调用位置原地替换为返回值
  • 无需提供返回值用void

5.5 注意点

  • 函数声明可以放在另一个函数的定义中,但函数定义不可以,不同函数的定义需要隔离开来
  • 一个函数只能返回一个值

5.6 实参与形参

int sum(int a,int b){return a+b;
}
int main(){int m = 1,n=2;int res = sum(m,n);return 0;
}

上述代码中:

  • a,b是形式参数
  • m,n是实际参数

注意:

  • 函数声明的形参只是一个说明,其实没有变量名都可以,但是函数定义的形参真实存在
  • 函数传参其实是将实际参数的值copy给形式参数作为初始化,不变量也允许作为形参,请见下面的例题:

在这里插入图片描述

6. 分支结构branch

6.1 if-else-else if语句

判断闰年的if语句
闰年:

  • (1)四年一闰百年不闰:即如果year能够被4整除,但是不能被100整除,则year是闰年。
  • (2)每四百年再一闰:如果year能够被400整除,则year是闰年。
int a;
scanf("%d",&a);
if(a%4){printf("NO");
}else{if(a%100){ printf("YES");}else if(a%400){printf("NO");}else{printf("YES");}
}

6.2 条件表达式

  • 比较运算符:==、>、<、>=、<=、!=
  • 条件表达式:通过比较运算符对左右操作数进行运算
  • 逻辑运算符:&&、||、!

使用逻辑表达式表达复杂的组合判断逻辑,仍然是闰年问题:

if(a%4!=0||a%100==0&&a%400!=0){printf("NO");
}else{printf("YES");
}

运算符优先级

  • 算数运算符>!>比较运算符>&&>||
  • 即:先运算,再比较,最后组合

逻辑表达式的短路

  • 如果a=1,那么a||b一定是1,不用考虑b,即b被短路
  • 如果a=0,那么a&&b一定是0,不用考虑b,即b被短路

7. 循环结构

循环三要素:起点、终点、步长

7.1 while

  • while的执行:出口判断->执行一次循环->出口判断…
  • do-while的执行:执行一次循环->出口判断->执行一次循环…

为了避免将形如a==0的判断语句写成a=0造成不执行的情况,可以写成0==a,因为0=a会报编译错误

7.2 for

  • for适用于迭代:能够不重不漏地访问范围内所有元素
    for (int i = 0; i < 1; ++i) {printf("%d",a++);}
  • for执行的顺序:

      1. int i =0;
      1. i<1;
      1. printf(“%d”,a++);
      1. ++i
      1. 回到2
  • for括号内的两个分号不能少

7.3 循环控制

  • break:提前终止当前整个循环
  • continue:跳过本轮循环剩下的执行内容,直接开始下一次

8.数组

8.1 数组组成

  • 基础数据类型:int、float类型的数组
  • 自定义数据类型:struct、union类型的数组

8.2 数组初始化

  • 通过列表初始化:
//全部初始化
int a[7]={0,1,2,3,4,5,6};
//部分初始化
int b[7]={0,1,2};//未初始化默认为0,故b[7]={0,1,2,0,0,0,0};
//不确定个数初始化
int c[]={0,1,2};
int c_size = sizeof(c)/4;//c_size=3
//注意sizeof计算的是字节数
  • 注意,只有数组定义时才能批量初始化,定义完成后只能通过索引 访问

8.3 数组长度

  • C语言中的数组特指定长数组
  • 因此定义数组元素数量必须使用常量或不变量
  • 准确来说,是编译期能直接确定数值的量
  • 已经定义好长度的数组,访问超过长度范围的索引值,会报数组越界(运行时错误)
获取已定义数组的元素数量
int length = sizeof(a)/sizeof(int);

8.4 数组遍历

形如下:

int a[n];
for(int i=0;i<n;i++){a[i]=i;
}

8.5 多维数组

  • 实际上是按顺序排列的

9. 结构体

9.1 声明结构体

struct item{	//1.声明结构体int id;
};
struct item a;	//2.定义结构体变量a.id = 10;		//3.访问结构体变量的成员
  • 声明:让编译器知道存在这么一个东西
  • 定义:让编译器实际生成一个东西(分配空间)
声明与定义的两种形式
  • 先声明后定义
  • 声明并定义
    在这里插入图片描述
typedef关键字
typedef unsigned long long uint64;uint64 a;//= unsigned long long a;
  • typedef不是宏定义替换
  • typedef可以给类型取别名

注意与结构体声明并定义的区别!!
在这里插入图片描述

9.2 使用结构体

初始化结构体内部的成员变量
typedef struct student{char name[20];unsigned long long id;int age;float score;
}S;
//不得用等号,要用冒号
S s1 = {"Mike",2222,age:19,score:100.0f};//如果按照顺序初始化,可以不标注所赋值变量名 
结构体大小
  • 使用sizeof获取结构体变量所占内存大小,原则上来说,大小等于其所有数据成员大小之和
  • 例外情况:内存对齐:通常是4字节对齐,即如果定义结构体大小不是4字节的整数倍那么将向上对4取整

在这里插入图片描述

9.3 联合体union

联合体存在的意义

为什么有了结构体还要有联合体?

  • 场景1:各个成员互斥,同一时间只有一项生效
  • 场景2:同一个数据可以合起来解读,也可以分开多部分解读

联合体在内存资源紧张的平台(如嵌入式)广泛使用
在这里插入图片描述

计算内存空间占用问题
  • union没有内存空间对齐的要求,内存空间占用即为最大成员的内存空间占用
  • struct有内存空间对齐的要求,内存空间占用是所有成员占用空间总和,还要注意对4向上取整

在这里插入图片描述

联合体各个数据成员共享空间,对任意成员的修改都会反映到所有数据上

在这里插入图片描述

9.4 枚举类型enum

    enum day {a=1,b,c,d,e,f,g};enum day dd = b;printf("%d %d",dd,e);//输出:2 5

参考上述代码可知,enum相当于定义了一系列变量,默认按照递增顺序给未赋值的变量赋值。

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Swin_transformer模型解析

目录 •1、网络整体框架 •2 、Patch Merging •3 、W-MSA MSA模块计算量 W-MSA模块计算量 •4、 SW-MSA •5 、Relative Position Bias •1、网络整体框架 •2 、Patch Merging 这里看着挺复杂&#xff0c;其实就相当于先对特征图进行LayerNorm&#xff0c;然后再进行一…

webapi 允许跨域

1.在Nuget安装webapi.cors 添加完会有这个包 然后在项目App_Start 目录下的WebApiConfig.cs里面添加 // Web API 配置和服务// 添加跨域设置config.EnableCors(new EnableCorsAttribute("*", "*", "*"));

CSS基础选择器 小案例复习(画三个小盒子)

&#xff08;大家好&#xff0c;前面我们学习了基础的选择器&#xff0c;俗话说&#xff1a;温故而知新。所以今天我们将通过小案例来复习前面学过的小知识点。另&#xff0c;十分感谢大家对我文章的支持❤️&#xff09; 通过这个案例复习两个地方&#xff1a; 类选择器的使用…

GICv3学习

中断分组 GICD_CTLR&#xff1a;配置是否支持group0、安全group1、非安全group1中断&#xff1b; 怎么配置中断在哪个组&#xff1b; 怎么知道中断是安全的还是非安全的&#xff1b; GICD_IGROUPR&#xff1a; 配置中断分组、中断是安全还是非安全&#xff1b; 4.4 软件产生中…

北方经贸经济类知网收录月刊投稿发表论文

《北方经贸》期刊是由国家新闻出版总署批准&#xff0c;黑龙江省教育厅主管&#xff0c;黑龙江省经济管理干部学院主办的经济类综合期刊。期刊融理论性、知识性、实践性于一体&#xff0c;立足龙江&#xff0c;辐射全国&#xff0c;面向世界&#xff0c;注重研究解决重大现实理…

探索智慧物流园区系统的发展蓝图

在当今数字化时代&#xff0c;智慧物流园区系统正经历着深刻的变革和快速的发展。那么&#xff0c;智慧物流园区系统的发展趋势究竟是什么呢&#xff1f;让我们一同深入探讨。 &#xff08;1&#xff09;智能化是智慧物流园区系统的重要发展趋势之一。通过人工智能、大数据等先…

双机 Cartogtapher 建图文件配置

双机cartogtapher建图 最近在做硕士毕设的最后一个实验&#xff0c;其中涉及到多机建图&#xff0c;经过调研最终采用cartographer建图算法&#xff0c;其中配置多机建图的文件有些麻烦&#xff0c;特此博客以记录 非常感谢我的同门 ”叶少“ 山上的稻草人-CSDN博客的帮助&am…

文心一言指令词宝典之旅行篇

作者&#xff1a;哈哥撩编程&#xff08;视频号、抖音、公众号同名&#xff09; 新星计划全栈领域优秀创作者博客专家全国博客之星第四名超级个体COC上海社区主理人特约讲师谷歌亚马逊演讲嘉宾科技博主极星会首批签约作者 &#x1f3c6; 推荐专栏&#xff1a; &#x1f3c5;…

【C++】理解vector的底层原理并模拟实现(手撕vector)

目录 01.成员变量 02.构造与析构 03.管理内存 1.reserve函数 2.reszie函数 04.访问元素 05.修改元素 之前的一篇博客讲到了vector的介绍及其运用&#xff1a;vector的介绍及使用说明 但是我们不仅要会用&#xff0c;还要理解它的底层原理&#xff0c;今天我们通过手撕一个…

wireshark解析grpc/protobuf的方法

1&#xff0c;wireshark需要安装3.20以上 下载地址&#xff1a;https://www.wireshark.org/ 2&#xff0c;如果版本不对&#xff0c;需要卸载&#xff0c;卸载方法&#xff1a; sudo rm -rf /Applications/Wireshark.app sudo rm -rf $HOME/.config/wireshark sudo rm -rf /…

设计模式-结构型-享元模式Flyweight

享元模式的特点&#xff1a; 享元模式可以共享相同的对象&#xff0c;避免创建过多的对象实例&#xff0c;从而节省内存资源 使用场景&#xff1a; 常用于需要创建大量相似的对象的情况 享元接口类 public interface Flyweight { void operate(String extrinsicState); } 享…

报错 | 2023新版IDEA/PyCharm连接远程服务器的Docker需使用密钥认证

文章目录 01 问题情景02 需求场景及工作原理03 解决步骤3.1 在本地生成密钥对3.2 将公钥保存至服务器3.3 本地连接时选择私钥文件 网上有很多文章讲怎么解决&#xff0c;但都要么写得很复杂&#xff0c;要么没有写明白原理或操作详情&#xff0c;造成我一头雾水。 01 问题情景…