量子代码工艺:掌握位运算符和名称空间设计的艺术

简介: 量子代码工艺:掌握位运算符和名称空间设计的艺术

1. 位运算符

1.1 位运算

位运算是对二进制数的位进行操作的运算。在C++语言中,共有6个位运算符:按位与(&)、按位或(|)、按位异或(^)、按位取反(~)、左移位(<<)和右移位(>>)。下面是一些位运算的实际案例和代码分析。


【例1-1】位运算符


位运算符可以用于对二进制数的位进行操作。例如,按位与运算符(&)可以对两个二进制数的对应位进行与操作,并返回一个新的二进制数。

#include <iostream>
using namespace std;
int main() 
{
    int a = 5; // 二进制表示为 101
    int b = 3; // 二进制表示为 011
    int result = a & b; // 将对应位进行与操作       
    cout << result << endl; // 输出结果为 1,二进制表示为 001      
    return 0;
}

在上面的例子中,我们定义了两个整数变量a和b,它们的二进制表示分别为101和011,然后使用按位与运算符将它们的对应位进行与操作,得到的结果是001,转换为十进制即为1。


【例1-2】左移位与右移位运算符


左移位运算符(<<)和右移位运算符(>>)用于将一个二进制数的所有位向左或向右移动指定的位数。

#include <iostream>
using namespace std;
int main() 
{
    int num = 5; // 二进制表示为 101
    int result1 = num << 2; // 将所有位向左移动2位
    int result2 = num >> 1; // 将所有位向右移动1位       
    cout << result1 << endl; // 输出结果为 20,二进制表示为 10100
    cout << result2 << endl; // 输出结果为 2,二进制表示为 10     
    return 0;
}

在上面的例子中,我们定义了一个整数变量num,它的二进制表示为101,然后使用左移位运算符将所有位向左移动2位,得到的结果是10100,转换为十进制即为20。接着使用右移位运算符将所有位向右移动1位,得到的结果是10,转换为十进制即为2。


1.2 位运算符应用举例

位运算符在实际应用中有很多用途。下面是一个例子,演示如何使用位运算符将一个整数的指定位设置为1或0。


【例1-3】将一个整数的指定位设置为1或0

#include <iostream>
using namespace std;
void setBit(int& num, int pos, int value) 
{
    int mask = 1 << pos; // 创建一个只有指定位为1的掩码
    if (value == 1) 
    {
        num |= mask; // 将指定位设置为1,使用按位或运算符
    }
     else if (value == 0) 
    {
        num &= ~mask; // 将指定位设置为0,使用按位与运算符和按位取反运算符
    }
}
int main() 
{
    int num = 5; // 二进制表示为 101 
    // 将指定位设置为1
    setBit(num, 1, 1); // 设置第1位为1
    cout << num << endl; // 输出结果为 7,二进制表示为 111       
    // 将指定位设置为0
    setBit(num, 2, 0); // 设置第2位为0
    cout << num << endl; // 输出结果为 3,二进制表示为 011       
    return 0;
}

在上面的例子中,我们定义了一个函数setBit,它接受一个整数num、一个表示位位置的pos和一个表示要设置的值的value。函数中根据value的值创建一个只有指定位为1的掩码,并根据value的值使用按位或运算符或按位与运算符和按位取反运算符将指定位设置为1或0。然后在主函数中可以调用setBit函数来将指定位设置为1或0,并输出结果。


2. 结构类型

结构类型是一种用户自定义的数据类型,可以将多个不同类型的数据组织在一起形成一个新的类型。通过结构类型,我们可以方便地将相关数据进行封装和管理,提高代码的可读性和维护性。


2.1 结构类型与结构变量的定义

在C++中,我们可以使用struct关键字定义结构类型。结构类型的定义格式如下:

struct 结构名 
{
    数据类型1 成员名1;
    数据类型2 成员名2;
    ...
};

结构名是我们为结构类型起的名称,成员名是我们为结构中的各个数据成员起的名称,数据类型是成员的数据类型。


【例1-4】 展示了结构变量的定义和使用:

#include <iostream>
using namespace std;
struct Person 
{
    string name;
    int age;
    float height;
};
int main() 
{
    Person p1; // 定义一个Person类型的结构变量p1
    p1.name = "Alice";
    p1.age = 20;
    p1.height = 165.5;
    cout << "Name: " << p1.name << endl;
    cout << "Age: " << p1.age << endl;
    cout << "Height: " << p1.height << endl;
    return 0;
}

在例1-4中,我们定义了一个名为Person的结构类型,它有三个成员,包括姓名name、年龄age和身高height。然后我们在main函数中定义了一个Person类型的结构变量p1,并给它的成员赋值。最后,我们输出了p1的成员值。


2.2 结构类型的嵌套与结构变量的初始化

结构类型可以嵌套定义,即结构类型的成员可以是其他结构类型。结构变量的初始化可以通过以下两种方式完成:


使用成员初始化列表。

逐个给成员赋值。

【例1-5】 展示了结构变量的初始化方式:

#include <iostream>
using namespace std;
struct Date 
{
    int year;
    int month;
    int day;
};
struct Person 
{
    string name;
    Date birthday;
};
int main() 
{
    Person p1 = {"Alice", {2000, 10, 1}}; // 使用成员初始化列表
    Person p2;
    p2.name = "Bob";
    p2.birthday.year = 1999; // 逐个给成员赋值
    p2.birthday.month = 9;
    p2.birthday.day = 30;
    cout << "Name: " << p1.name << endl;
    cout << "Birthday: " << p1.birthday.year << "-" << p1.birthday.month << "-" << p1.birthday.day << endl;
    cout << "Name: " << p2.name << endl;
    cout << "Birthday: " << p2.birthday.year << "-" << p2.birthday.month << "-" << p2.birthday.day << endl;
    return 0;
}

在例1-5中,我们定义了两个结构类型,分别是Date和Person。Person结构类型的一个成员是Date类型的birthday。在main函数中,我们给两个Person类型的结构变量p1和p2进行了初始化,分别使用了成员初始化列表和逐个给成员赋值的方式。


2.3 结构数组与结构指针

结构数组是由结构类型的多个结构变量组成的数组。结构指针是指向结构类型的指针变量。


【例1-6】 使用结构数组保存5个学生信息:

#include <iostream>
using namespace std;
struct Student 
{
    string name;
    int age;
    float score;
};
int main() 
{
    Student students[5]; // 定义一个包含5个Student结构类型的数组
    for (int i = 0; i < 5; i++) 
    {
        cout << "Enter name: ";
        cin >> students[i].name;
        cout << "Enter age: ";
        cin >> students[i].age;
        cout << "Enter score: ";
        cin >> students[i].score;
    }
    cout << "Student Information:" << endl;
    for (int i = 0; i < 5; i++) 
    {
        cout << "Name: " << students[i].name << endl;
        cout << "Age: " << students[i].age << endl;
        cout << "Score: " << students[i].score << endl;
    }
    return 0;
}

在例1-6中,我们定义了一个包含5个Student结构类型的数组students。然后,通过for循环对数组中的每个结构变量进行逐个赋值。最后,我们输出了学生的信息。


【例1-7】使用结构指针处理学生成绩:

#include <iostream>
using namespace std;
struct Student 
{
    string name;
    float score;
};
void updateScore(Student *student, float newScore) 
{
    student->score = newScore; // 使用指针访问结构成员
}
int main() 
{
    Student s1 = {"Alice", 90.5};
    Student *p = &s1; // 定义一个指向Student类型的指针,并让它指向s1   
    cout << "Original Score: " << s1.score << endl;
    updateScore(p, 95); // 通过指针调用函数修改成绩
    cout << "Updated Score: " << s1.score << endl;    
    return 0;
}

在例1-7中,我们定义了一个Student类型的结构变量s1,并通过指针p指向它。然后,我们定义了一个函数updateScore来更新学生成绩,函数参数为一个指向Student类型的指针和一个新的成绩。在主函数中,我们输出了原始成绩,然后通过指针调用函数来修改成绩,最后再次输出修改后的成绩。


3. 联合

联合(Union)是一种特殊的数据类型,它允许我们在同一块内存空间中存储不同类型的数据。不同于结构体,联合只能同时存储一个成员的值,共享同一块内存空间。


3.1 联合变量的定义和使用

在C++中,我们可以使用union关键字定义联合类型。联合类型的定义格式如下:

union 联合名 
{
    数据类型1 成员名1;
    数据类型2 成员名2;
    ...
};

联合名是我们为联合类型起的名称,成员名是我们为联合中的各个成员起的名称,数据类型是成员的数据类型。


【例1-8】 展示了联合变量的定义和使用:

#include <iostream>
using namespace std;
union Value 
{
    int iValue;
    float fValue;
};
int main() 
{
    Value v;
    v.iValue = 10;
    cout << "Integer Value: " << v.iValue << endl;    
    v.fValue = 3.14;
    cout << "Float Value: " << v.fValue << endl;    
    return 0;
}

在例1-8中,我们定义了一个名为Value的联合类型,它有两个成员,一个是整型的iValue,另一个是浮点型的fValue。在main函数中,我们定义了一个Value类型的联合变量v,并给它的整型成员iValue赋值10,然后输出iValue的值。接着,我们给v的浮点型成员fValue赋值3.14,并输出fValue的值。注意,当我们给一个成员赋值时,其他成员的值会被覆盖。


3.2 求一个整数高位数和低位数

我们可以使用联合来求一个整数的高位数和低位数。具体实现方式如下:

【1-9】

#include <iostream>
using namespace std;
union Number 
{
    int num;
    struct 
    {
        int low;
        int high;
    } parts;
};
int main() 
{
    Number n;
    cout << "Enter a number: ";
    cin >> n.num;    
    n.parts.low = n.num % 100;
    n.parts.high = n.num / 100;    
    cout << "Low digit: " << n.parts.low << endl;
    cout << "High digit: " << n.parts.high << endl;    
    return 0;
}

在例1-9中,我们定义了一个联合类型Number,其中包含一个整型成员num和一个嵌套的结构体成员parts,parts中又包含一个低位数low和一个高位数high。在main函数中,我们定义了一个Number类型的联合变量n,并从用户输入获取一个整数值。然后,我们通过对整数进行求余和整除操作,将低位数和高位数存储到n的相应成员中。最后,我们输出低位数和高位数的值。


4. 枚举

枚举(enum)是C++中的一种数据类型,它允许我们为一组整数值定义有意义的名称。使用枚举可以提高代码的可读性和可维护性。本节将介绍枚举类型的基本语法和应用示例。


4.1枚举类型的定义

在C++中,可以使用enum关键字定义一个枚举类型。枚举类型的定义形式如下:

enum 枚举名 
{
    枚举元素1,
    枚举元素2,
    ...
};

其中,枚举名是一个标识符,用于表示这个枚举类型。枚举元素是整数常量,表示枚举类型的可能取值。


4.2 枚举类型的应用

枚举类型主要用于表示一组相关的取值,例如星期几、月份等。以下是一个使用枚举类型表示星期几的示例:

enum Weekdays 
{
    Monday,
    Tuesday,
    Wednesday,
    Thursday,
    Friday,
    Saturday,
    Sunday
};

在上述示例中,我们定义了一个名为Weekdays的枚举类型,包含了七个枚举元素,分别表示星期一到星期日。


4.3 使用枚举类型

在程序中使用枚举类型时,可以通过枚举名和枚举元素来表示具体的取值。以下是一个使用枚举类型的例子:

#include <iostream>
enum Weekdays  
{
    Monday,
    Tuesday,
    Wednesday,
    Thursday,
    Friday,
    Saturday,
    Sunday
};
int main() 
{
    Weekdays today = Monday;    
    std::cout << "Today is ";    
    switch (today) 
    {
        case Monday:
            std::cout << "Monday";
            break;
        case Tuesday:
            std::cout << "Tuesday";
            break;
        case Wednesday:
            std::cout << "Wednesday";
            break;
        case Thursday:
            std::cout << "Thursday";
            break;
        case Friday:
            std::cout << "Friday";
            break;
        case Saturday:
            std::cout << "Saturday";
            break;
        case Sunday:
            std::cout << "Sunday";
            break;
    }
    std::cout << std::endl;
    return 0;
}

以上代码首先定义了一个枚举类型Weekdays,然后在main函数中声明了一个名为today的变量,类型为Weekdays。在switch语句中根据today的值输出对应的星期几。


代码运行结果为:

Today is Monday

通过上述示例,我们可以看到枚举类型的应用可以使代码更加易读和易维护。在实际开发中,可以使用枚举类型来替代魔术数字,提高代码的可读性和可维护性。


C++学习笔记:名称空间


名称空间(namespace)是C++中的一个重要概念,用于解决命名冲突问题。本节将介绍名称空间的定义、使用和C++标准库的使用。


5. 名称空间

5.1 名称空间的定义与使用

名称空间允许我们在一个作用域中定义一组相关的名称,以避免名称冲突。可以通过namespace关键字来定义一个名称空间,如下所示:

namespace 名称空间名 
{
    // 声明、定义一些相关的变量、函数、类等
}

其中,名称空间名是一个标识符,用于表示这个名称空间。在名称空间中可以声明、定义一些与这个名称空间相关的变量、函数、类等。


以下是一个使用名称空间的示例:

#include <iostream>
namespace MyNamespace 
{
    void PrintHello() 
    {
        std::cout << "Hello, World!" << std::endl;
    }
}
int main() 
{
    MyNamespace::PrintHello();    
    return 0;
}

在上述示例中,我们使用了名称空间MyNamespace,其中定义了一个函数PrintHello。通过MyNamespace::PrintHello()的方式调用该函数。


代码运行结果为:

Hello, World!

【例1-10 】名称空间的定义与使用


以下是一个更加详细的示例,展示了如何在名称空间中定义变量、函数和类:

#include <iostream>
namespace MyNamespace 
{
    int x = 5;  // 定义一个整数变量
    void PrintHello() 
    {
        std::cout << "Hello, World!" << std::endl;
    }
    class MyClass 
    {
    public:
        void PrintX() 
        {
            std::cout << "x = " << x << std::endl;
        }
    };
}
int main() 
{
    std::cout << MyNamespace::x << std::endl;  // 访问名称空间中的变量
    MyNamespace::PrintHello();  // 调用名称空间中的函数
    MyNamespace::MyClass obj;   // 声明一个名称空间中的类的对象
    obj.PrintX();               // 调用类的成员函数
    return 0;
}

以上示例展示了名称空间的完整用法,注意在访问名称空间中的变量、函数和类时,需要使用名称空间名::的方式。


【例1-11】 使用using声明


在C++中,可以使用using声明来避免每次都使用名称空间名::的方式。使用using声明后,可以直接使用名称空间中的变量、函数和类。

#include <iostream>
namespace MyNamespace 
{
    void PrintHello() 
    {
        std::cout << "Hello, World!" << std::endl;
    }
}
int main() 
{
    using MyNamespace::PrintHello;
    PrintHello();  // 直接使用PrintHello函数,无需使用MyNamespace::
    return 0;
}

上述示例中,我们使用using MyNamespace::PrintHello;的方式声明了PrintHello,之后就可以直接使用PrintHello函数。


【例1-12】 使用using编译指令


除了使用using声明外,还可以使用using namespace编译指令来将整个名称空间引入当前作用域。

#include <iostream>
namespace MyNamespace 
{
    void PrintHello() 
    {
        std::cout << "Hello, World!" << std::endl;
    }
}
int main() 
{
    using namespace MyNamespace;
    PrintHello();  // 直接使用PrintHello函数,无需使用MyNamespace::
    return 0;
}

上述示例中,我们使用using namespace MyNamespace;的方式引入了整个MyNamespace名称空间,之后就可以直接使用PrintHello函数。


5.2 C++标准库

C++标准库是C++语言提供的一组核心功能和数据结构,方便开发者进行常用操作。标准库的内容包含在std名称空间中。


以下是一个使用C++标准库的示例:

#include <iostream>
int main() 
{
    std::cout << "Hello, World!" << std::endl;
    return 0;
}

在上述示例中,使用了std::cout和std::endl。这些函数和类都是位于C++标准库中的,需要使用std名称空间来访问。

————————————————

版权声明:本文为CSDN博主「麦当当兄弟肯德德」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。

原文链接:https://blog.csdn.net/qwsbcjendb/article/details/131812790

相关文章
|
8月前
|
人工智能 编解码 自然语言处理
VideoMind:Chain-of-LoRA突破时间盲区让AI真正看懂长视频
VideoMind是一种新型视频语言代理,专为解决长视频时间定位理解挑战设计。它通过“Chain-of-LoRA”技术结合四个专业角色(Planner、Grounder、Verifier、Answerer)实现高效推理。Planner分析查询并制定计划;Grounder精确定位视频时刻;Verifier验证候选时刻准确性;Answerer生成最终答案。此架构在14个公共基准上表现出色,尤其在长视频定位任务中超越了现有模型,同时保持高内存效率。VideoMind推动了多模态AI的发展,提供了解决复杂视频理解问题的新方法。
10418 5
|
前端开发
Bootstrap5 消息弹窗(Toasts)3
本示例展示了如何使用HTML和Bootstrap创建并显示多个消息弹窗。通过设置`.toast-container`类及相应的位置属性,可以轻松控制弹窗的布局与间距。每个弹窗包含标题、时间戳及关闭按钮,支持自定义内容显示。
|
10月前
|
人工智能 Linux API
零门槛本地部署!手把手教你用Ollama+Chatbox玩转DeepSeek大模型
本教程介绍如何在个人电脑上免费部署DeepSeek模型,无需高端显卡。通过Ollama和Chatbox两款轻量工具,用户可以在普通CPU上流畅运行大型语言模型。Ollama支持跨平台操作,提供一键式安装和模型管理;Chatbox则是多平台AI客户端,支持多种主流模型。教程涵盖Ollama和Chatbox的安装、DeepSeek模型的下载与配置,帮助你在本地轻松搭建智能助手,适用于学术研究、代码编写和日常问答等场景。
3938 19
零门槛本地部署!手把手教你用Ollama+Chatbox玩转DeepSeek大模型
|
缓存 算法 关系型数据库
MIT韩松团队长上下文LLM推理高效框架DuoAttention:单GPU实现330万Token上下文推理
麻省理工学院韩松团队提出DuoAttention框架,旨在提高大型语言模型(LLM)处理长上下文的效率。该框架通过区分检索头和流式头,仅对检索头应用全键值缓存,减少内存消耗和计算时间,同时保持模型长上下文处理能力。实验结果显示,DuoAttention在多种模型架构上显著提升了推理效率,为LLM的实际应用提供了新可能。
347 14
|
机器学习/深度学习 数据可视化 算法
图特征工程实践指南:从节点中心性到全局拓扑的多尺度特征提取
本文详细介绍了如何利用NetworkX库从图结构中提取重要特征。首先,通过定义辅助函数设置了图的可视化选项,并以Zachary网络数据集为例进行了可视化展示。接着,文章深入探讨了三类图特征:基于节点的特征(如节点度、中心性等)、基于边的特征(如最短路径、邻域重叠等)以及基于图的特征(如Graphlets、Weisfeiler-Leman特征等)。通过这些特征的提取与分析,可以全面理解网络结构,识别关键节点,分析信息流动模式,并发现潜在的隐藏模式。本文不仅展示了如何应用这些特征来揭示社交网络中的角色和联系,还强调了其在交通网络分析和生物系统研究等领域的广泛应用潜力。
696 12
图特征工程实践指南:从节点中心性到全局拓扑的多尺度特征提取
|
人工智能 安全 Android开发
探索安卓与iOS的安全性差异:一场永无止境的较量
在移动操作系统的领域中,安卓(Android)和iOS以其独特的优势各自占领了市场的一大半江山。但它们在安全性上的差异,一直是业界和用户关注的焦点。本文将深入分析这两个平台的安全架构、更新机制以及隐私保护措施等方面的差异,揭示它们如何在不断的攻防对抗中进化,以及这些差异对用户选择的潜在影响。通过比较研究,我们将探讨哪种系统更能有效地保护用户免受恶意软件和网络攻击的威胁,并讨论未来移动安全趋势可能如何塑造这两种系统的发展方向。
399 0
|
机器学习/深度学习 人工智能 自然语言处理
|
Oracle 关系型数据库 MySQL
入职必会-开发环境搭建17-IDEA连接数据库
IntelliJ IDEA集成了众多插件,方便开发者使用,使用IDEA自带的Database模块就可以很方便的配置、连接数据库,在 IntelliJ IDEA 中连接数据库,可以按照以下步骤进行操作。
827 0
|
前端开发
(css必看)禁止用户拖动,禁止选中复制,禁止输入框输入
(css必看)禁止用户拖动,禁止选中复制,禁止输入框输入
682 1
聚焦实战技能,剖析底层原理:Netty+Redis+ZooKeeper+高并发实战
移动时代、5G时代、物联网时代的大幕已经开启,它们对于高性能、高并发的开发知识和技术的要求,抬升了Java工程师的学习台阶和面试门槛。