二、重学C++—C语言核心

上一章节:

一、重学C++—C语言基础-CSDN博客https://blog.csdn.net/weixin_36323170/article/details/146002496?spm=1001.2014.3001.5502

本章节代码:

cPart2 · CuiQingCheng/cppstudy - 码云 - 开源中国https://gitee.com/cuiqingcheng/cppstudy/tree/master/cPart2

一、数组

数组:可以形象理解为一个整齐放置盒子的架子,每个盒子里放置了一种定义好类型的数据,每个盒子有自己的编号,编号为整型,从0依次往上递增。

1、数组的定义与使用

类型 数组名[数组大小]

int number[5];
1.1关于数组大小的三点说明:

(1)、数组若在定义时,不给数组赋值,则必须要指定其数组大小,且数组大小为常量,可以是数值常量,也可以是普通常量,这里就可以联系上面例子,列举放盒子的架子,一样,如果都不知道有多少个盒子,那么数组这个架子该如何创建大小。

(2)、数组若定义时,就给初始化赋值了,如下:

int number[]={1,2,3,4,5};

这里就已经指定了多少个放数据的盒子,所以这里就可以不需要对数组大小进行说明。

(3)、除了上述两种,当数组作为形参时,不需要指定大小。(形参,可以先记下,后续函数中会讲解)

void printArray(int arr[]) {// 函数体
}
1.2、二维数组和多维数组

二维数组:一维数组构成的架子垒起来,按照行进行存储数据;

二维数组中可以把 行数省略,列数不能省略

int a[4][4];
int b[][4] = {1,2,3,4,21,22,23,24};

多维数组:a[][3][4]....:只能省略第一个[]中的数

        // 数组int a[10];for(int i = 0; i < 10; ++i){a[i] = i*10;}printf("arr a size : %d\n", sizeof(a));// 获取数组所占字符数int  b[SIZE];for(int j = 0; j < SIZE ; j++){b[j] = a[j] / 2;}float fArr[] = {3.4, 4.5, 6.6};int num[2][4];int nn[][2] = {1,2,3,4,21,22,23,24}; // 多维数组初始化后可以不指定,第一维大小

二、指针

指针可以理解成是一个特殊的 “身份证”,这个身份证上记录着某个东西存放的位置,以及这个位置的名称。

指针的本质

在计算机的内存里,每个存储单元都有一个独一无二的地址,就好像每个房间都有一个门牌号一样。指针就是用来存放这些地址的变量。

例如:

int num = 10;
int *p;                // 指针的定义
p = &num;              // '&'这个符号时取地址,将地址值付给指针P
printf("%d\n", *p);    // '*'这个符号表示取值,表示将P这个地址下的值取出来。
printf("pointer size:%d\n", sizeof(p));     // 获取指针大小,32位系统,就是4个字节,64位系统,就是8个字节;
printf("pointer = %p\n",p);//%p表示按照16进制的形式输出

指针用来存放内存地址,因为在同一个系统下,指针的大小是固定的,比如在32位系统下,指针对应的大小就是4个字节。

指针相关的运算符

&:取地址运算符,运算结果为操作数的指针

*:指针运算符,运算结果为指针所指向的数据的引用

指针进行 +/-运算。

        int *p;                // 指针的定义p = &num;              // '&'这个符号时取地址,将地址值付给指针Pprintf("%d\n", *p);    // '*'这个符号表示取值,表示将P这个地址下的值取出来。printf("pointer size:%d\n", sizeof(p));     // 获取指针大小,32位系统,就是4个字节,64位系统,就是8个字节;printf("pointer = %p\n", p);//%p表示按照16进制的形式输出指针地址。int data[4] ={3,4,5,6};int *pNum = data;           // 数组名为指针,数组名是指针常量,不能改变。pNum++;printf("pNum -> value: %d\n", *pNum);   // 指针 ++,表示指针所直指向的内存地址,增加了一个int型数据的间隔。所以这里输出 4int *pData = &data[3];  // 将数组的第四个数据地址赋值给pData;pData -= 1;printf("pData -> value: %d\n", *pData);   // 指针-1,表示指针所直指向的内存地址,减少了一个int型数据的间隔。所以这里输出 5// 指针在进行加减时,要注意不要访问越界。

指针常量(指针类型的常量:指针本身市场量):一旦定义就不能被赋值、改变,但是可以改变指针所指向的数据。

常量指针(常量的指针:指针指向的是常量):它被指向的一个数是一个常量(在指针看来,也就是说通过p无法去修改它所指向的地址的数据,但是p本身是变量,可以对他进行赋值,更改

常量指针常量(指针本身是常量,指针指向的也是常量):定义的标识符是个常量的指针所以他的值不能任意改变,也就是他所指向的地址值不能变,同时由于他是一个指针型的常量,所以他对应的地址的值,不能是赋值,只能读取。

二级指针和多级指针

二级指针,指针的指针,即指针变量的地址;这里一般用于存放某个数据单元的地址的地址,这样要修改这个地址下创建的地址,可以这样使用,建议不要用太多级指针。一般到二级,就可以了,否则代码可读性会大大降低,从而增加调试理解难度。

三、函数

函数:可以形象的理解为一个个小的 “工作车间”,每个车间都有特定的任务,能帮你把复杂的大工作拆分成很多小工作,让程序更有条理。

函数定义:

上面形象的把函数比喻成一个“工作车间”,那么一个车间实现某个具体功能时,往往需要原材料,即函数参数-》形参,函数工作完了,会输出一个结果,或者是返回某个状态,这里就有返回值,跟出参的概念。

例如下,计算两数之和:

int add(int a, int b) {return a + b;
}
  • int:这是函数的返回类型,说明这个函数做完工作后会返回一个整数。
  • add:这是函数的名字,就像车间的名字,方便我们后面调用它。
  • (int a, int b):这是函数的参数列表,也就是这个车间需要的材料。这里需要两个整数ab
  • return a + b;:这是函数的核心工作内容,把两个数相加,然后把结果返回出去。

函数调用:

函数的声明定义,必须要在函数调用前,这里很好理解,若为进行声明定义,那么调用处怎么会知道这个函数的组成。

定义好函数后,就可以在其他地方调用它,就像在需要的时候去使用某个车间。比如:

#include <stdio.h>int add(int a, int b) {return a + b;
}
void addOutput(int n, int m, int *sum)
{*sum = n+m;n+=5;m+=10;if((*sum) < 400){addOutput(n,m,sum); // 递归调用}
}int main() {int result = add(3, 5);printf("两数之和是: %d\n", result);int sum = 0, k = 66;addOutput(result, k, &sum);    // 这里的sum是出参, result/k,为入参 返回值为voidprintf("sum: %d, k = %d, result=%d \n", sum, k, result);int (*pAdd)(int, int);  // 函数指针pAdd = add;int ret = pAdd(39,45);printf("ret: %d\n", ret);return 0;
}

函数的递归调用:即在函数执行代码段中的某一个环节,继续调用该函数,这里要注意,递归要设立退出机制,不能让函数一直处于递归调用循环的状态。

函数的作用

代码复用:如果有一段代码需要在不同的地方多次使用,就可以把它写成一个函数。这样每次需要用的时候,直接调用函数就行,不用重复写代码。比如上面的add函数,在很多地方要计算两数之和时,都能调用它。

模块化设计:把一个大的程序拆分成很多小的函数,每个函数负责一个小任务。这样程序的结构会更清晰,也更容易维护和调试。就像一个大工厂,分成很多小车间,每个车间负责一部分工作,管理起来更方便。

函数代码太长,要进行拆分成小的功能模块。

函数的参数和返回值

函数的参数:就是如上面的 int a, int b,这里为函数的形参,按照功能又可以分为,入参,跟出参,比如这里的sum就是出参,传递的是指针,在函数执行完后,指针指向的位置,值发生了修改,而另外两个参数的值不发生改变。

返回值:函数可以有返回值,也可以没有返回值(返回类型为

void)。返回值就像是车间产出的产品,函数做完工作后把结果返回出去。如果函数不需要返回结果,就用

void作为返回类型。

函数指针:函数名为函数的指针。

四、结构体

结构体就像是一个 “收纳盒”,可以把不同类型的数据收纳在一起,形成一个新的数据类型。

结构体的定义

定义结构体就像是设计一个收纳盒,要说明这个盒子里可以放哪些东西。比如,你想设计一个收纳盒来存放一个人的信息,包括姓名、年龄和身高,就可以这样定义:

struct Person {char name[20];  // 姓名int age;        // 年龄float height;   // 身高
};

结构体变量的定义和使用

定义好结构体后,就可以用它来创建具体的变量,就像按照设计好的收纳盒样式做出一个个实际的盒子。例如:

#include <stdio.h>
#include <string.h>struct Person {char name[20];int age;float height;
};int main() {// 定义一个结构体变量struct Person p1;// 给结构体变量的成员赋值strcpy(p1.name, "张三");p1.age = 20;p1.height = 1.75;// 输出结构体变量的成员值printf("姓名: %s\n", p1.name);printf("年龄: %d\n", p1.age);printf("身高: %.2f\n", p1.height);return 0;
}

结构体的作用

组织数据:当需要处理一组相关的数据时,把它们放在一个结构体里,能让数据的组织更有条理。比如上面的例子,把一个人的姓名、年龄和身高放在一个结构体里,方便对这个人的信息进行管理。

函数参数传递:可以把结构体作为函数的参数传递,这样就能一次性传递多个相关的数据。例如,写一个函数来打印辆车的信息:

#include <stdio.h>
#include <string.h>
struct Person {char name[20];int age;float height;
};typedef struct car{char name[20];  // 名称float  wight;     // 宽高float height;char colorChr[20];  //颜色
}CAR;void printCar(CAR C1) {printf("品牌: %s\n", C1.name);printf("颜色: %s\n", C1.colorChr);printf("高: %.2f\n", C1.height);printf("宽: %.2f\n", C1.height);
}int main() {// 定义一个结构体变量struct Person p1;// 给结构体变量的成员赋值strcpy(p1.name, "张三");p1.age = 20;p1.height = 1.75;// 输出结构体变量的成员值printf("姓名: %s\n", p1.name);printf("年龄: %d\n", p1.age);printf("身高: %.2f\n", p1.height);// 定义一个变量车CAR C1;strcpy(C1.name, "奔驰");strcpy(C1.colorChr, "red");C1.height = 1.7;C1.wight = 2.2;printCar(C1);return 0;
}

注意:

在暴露给外部调用时,尽量不要使用结构体传参数,这样针对只是少数值修改时,不需要创建整个结构体对象。

五、共用体(使用场景较少)

在 C 语言里,共用体(也叫联合体)就像是一个特殊的 “小房间”,这个房间每次只能住 “一个人”,也就是每次只能存放一种数据,但可以存放不同类型的数据。

共用体的定义

定义共用体就像是设计这个特殊的 “小房间”,要说明这个房间可以让哪些 “人” 住进来,也就是能存放哪些类型的数据。比如,你设计一个房间,它既可以让一个整数 “住”,也可以让一个浮点数 “住”,就可以这样定义:

union Data {int i;float f;
};

union:这是定义共用体的关键字。

Data:这是共用体的名字,就像房间的名字,方便后面使用。

大括号里的内容就是这个房间可以容纳的数据类型,这里有一个整数i和一个浮点数f。

共用体变量的定义和使用

定义好共用体后,就可以用它来创建具体的变量,就像按照设计好的房间样式造一个实际的房间。例如:

#include <stdio.h>union Data {int i;float f;
};int main() {// 定义一个共用体变量union Data d;// 给共用体变量的整数成员赋值d.i = 10;printf("整数的值: %d\n", d.i);// 给共用体变量的浮点数成员赋值d.f = 3.14;printf("浮点数的值: %.2f\n", d.f);printf("整数的值: %d\n", d.i);// 这里整型数据已经被覆盖return 0;
}

在这个例子中,union Data d;创建了一个名为d的共用体变量。然后通过.操作符来访问共用体变量的成员,给它们赋值并输出。要注意,每次给一个成员赋值后,之前存的数据就会被覆盖,因为这个 “小房间” 每次只能住 “一个人”。

共用体可以节省内存空间,现阶段,内存空间往往十分充裕,因而,共用体使用面就减少了。

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

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

相关文章

2-003:MySQL 三层 B+ 树能存多少数据?

1. 计算 B 树能存储多少数据 参数设定 每个数据页&#xff08;Page&#xff09;大小&#xff1a;16KB&#xff08;16384 字节&#xff09;每个索引节点存储的子节点数量&#xff1a; 索引项大小&#xff1a; 假设 bigint&#xff08;主键&#xff09;占 8 字节每个索引项存储…

几种常见的虚拟环境工具(Virtualenv、Conda、System Interpreter、Pipenv、Poetry)的区别和特点总结

在 PyCharm 中创建虚拟环境是一个非常直接的过程&#xff0c;可以帮助你管理项目依赖&#xff0c;确保不同项目之间的依赖不会冲突。 通过 PyCharm 创建虚拟环境 打开 PyCharm 并选择或创建一个项目。 打开项目设置&#xff1a; 在 Windows/Linux 上&#xff0c;可以通过点击…

Windows系统编程项目(四)窗口管理器

本章我们讲解基于对话框的MFC窗口相关的操作 该管理器要实现以下功能 初始化列表 初始化列表表头 初始化图像列表 初始化列表 功能实现 加载菜单 刷新列表 结束进程 隐藏窗口 最大化窗口 最小化窗口 手搓窗口管理器 // CWindowManage.cpp: 实现文件 //#include "pch.h&…

优化 NFS 挂载参数以提升可靠性与容错性

在现代 IT 基础设施中&#xff0c;NFS&#xff08;网络文件系统&#xff09;被广泛用于共享文件和存储。虽然 NFS 提供了便利&#xff0c;但在某些情况下&#xff0c;挂载失败或网络问题可能导致挂载操作不稳定。为了提高挂载的可靠性和容错性&#xff0c;我们可以通过优化 NFS…

JavaScript事件循环机制

JavaScript 事件循环机制&#xff08;Event Loop&#xff09;详解 JavaScript 是 单线程、非阻塞 语言&#xff0c;依赖 事件循环&#xff08;Event Loop&#xff09; 来实现异步编程。它的执行模型包括 调用栈&#xff08;Call Stack&#xff09;、任务队列&#xff08;Task …

大模型架构记录4-文档切分 (chunks构建)

chunks&#xff1a; 块 trunks : 树干 “RAG”通常指 检索增强生成&#xff08;Retrieval-Augmented Generation&#xff09; 主要框架&#xff1a;用户提query&#xff0c;找到和它相关的&#xff0c;先把问题转换为向量&#xff0c;和向量数据库的数据做比较&#xff0c;检…

物联网IoT系列之MQTT协议基础知识

文章目录 物联网IoT系列之MQTT协议基础知识物联网IoT是什么&#xff1f;什么是MQTT&#xff1f;为什么说MQTT是适用于物联网的协议&#xff1f;MQTT工作原理核心组件核心机制 MQTT工作流程1. 建立连接2. 发布和订阅3. 消息确认4. 断开连接 MQTT工作流程图MQTT在物联网中的应用 …

第27周JavaSpringboot电商进阶开发 1.企业级用户验证

课程笔记&#xff1a;注册邮箱验证 一、概述 从本小节开始&#xff0c;将学习如何进行注册邮箱验证。主要任务是给项目配置一个公共邮箱&#xff08;可自己注册或由公司提供&#xff09;&#xff0c;用于向用户发送验证码&#xff0c;帮助用户完成注册流程。课程中以QQ邮箱为…

数据库---sqlite3

数据库&#xff1a; 数据库文件与普通文件区别: 1.普通文件对数据管理(增删改查)效率低 2.数据库对数据管理效率高,使用方便 常用数据库: 1.关系型数据库: 将复杂的数据结构简化为二维表格形式 大型:Oracle、DB2 中型:MySql、SQLServer …

音视频软件工程师面试题

一、基础知识 编解码相关 H.264 和 H.265(HEVC)的主要区别是什么?视频编解码的基本流程是什么?关键技术有哪些?音频编解码(如 AAC、MP3、Opus)的区别和应用场景?什么是 B 帧、P 帧、I 帧?它们的作用是什么? 流媒体协议RTMP、HTTP-FLV、HLS、WebRTC 的区别和应用场景…

【系统架构设计师】测试方法

目录 1. 说明2. 静态测试3. 动态测试4. 黑盒测试5. 白盒测试6. 灰盒测试7. 自动化测试8.例题8.1 例题1 1. 说明 1.软件测试方法的分类有很多种&#xff0c;以测试过程中程序执行状态为依据可分为静态测试&#xff08;Static Testing&#xff0c;ST&#xff09;和动态测试&…

tomcat配置应用----server.xml文件具体配置

1.tomcat项目目录 默认项目目录&#xff1a;tomcat安装目录/webapps目录 如上图所示&#xff0c;在tomcat的项目目录下有很多子文件夹&#xff0c;这些子文件夹中都有一个项目首页。 如上图所示&#xff0c;将来我们去使用IP加端口号的方式去访问tomcat的时候&#xff0c;默认是…

Spring Boot 调用DeepSeek API的详细教程

目录 前置准备步骤1&#xff1a;创建Spring Boot项目步骤2&#xff1a;配置API参数步骤3&#xff1a;创建请求/响应DTO步骤4&#xff1a;实现API客户端步骤5&#xff1a;创建控制器步骤6&#xff1a;异常处理步骤7&#xff1a;测试验证单元测试示例Postman测试请求 常见问题排查…

多维数据聚合方案:SQL GROUPING SETS深度解析

一、什么是GROUPING SETS&#xff1f; GROUPING SETS是SQL标准中的多维聚合运算符&#xff0c;允许在单个查询中实现多维度组合的分组统计。相较于传统UNION ALL方案&#xff0c;性能可提升3-10倍&#xff08;TPC-DS基准测试&#xff09;。 二、核心语法解析 SELECT column1,…

Excel中国式排名,3种方法!

大家好&#xff0c;我是小鱼。 什么是中国式排名呢&#xff1f; 举个例子比如说公司一共有10名员工进行成绩考核&#xff0c;如果9个人考核成绩都是90分&#xff0c;你是89分&#xff0c;按照国际惯用的排名法则&#xff1a;9 个人考核成绩并列第一&#xff0c;你第10名&…

哪些业务场景更适合用MongoDB?何时比MySQL/PostgreSQL好用?

哪些业务场景更适合用MongoDB&#xff1f;何时比MySQL/PostgreSQL好用&#xff1f; 就像淘宝的个性化推荐需要灵活调整商品标签&#xff0c;MongoDB这种"变形金刚"式的数据库&#xff0c;在处理以下三类中国特色业务场景时更具优势&#xff1a; 一、动态数据就像&q…

深度解读:OpenAI发布GPT-5的技术突破与商业影响

引言 2025年2月&#xff0c;OpenAI正式发布GPT-5&#xff0c;这一被誉为“AI新纪元开篇之作”的模型&#xff0c;不仅实现了技术架构的颠覆性创新&#xff0c;更以免费开放策略引发行业地震。本文将从技术突破、商业影响、行业竞争格局及未来挑战四个维度&#xff0c;全面解析…

网络防火墙是什么有什么用_网络防火墙:守护信息安全的重要屏障

网络防火墙的基本概念 网络防火墙是网络安全领域的重要组成部分&#xff0c;它充当着内部网络和外部网络之间的安全防护层。防火墙能够监控和控制进出网络的数据流&#xff0c;只允许符合安全策略的信息通过&#xff0c;从而有效阻止潜在威胁的入侵。简而言之&#xff0c;网络…

C# WPF 串口通信

C# WPF 串口通信 安装依赖库 安装依赖库 System.IO.Ports using System.Diagnostics; using System.IO.Ports; using System.Text; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windo…