`

C语言中的位运算&结构体浅析 — <编程之美>1.2学习笔记

 
阅读更多

引子问题:

中国象棋将帅问题:

在一把象棋的残局中,象棋双方的将帅不可以相见,即不可以在中间没有其他棋子的情况下在同一列出现。而将、帅各被限制在己方的3*3的格子中运动。相信大家都非常熟悉象棋的玩法吧,这里就不详细说明游戏规则了。

用A、B代表将和帅,请写出一个程序,输出A、B所有合法的位置。要求在代码中只能用一个变量。

分析与解法:

这个问题的解法并不复杂。

遍历A的所有位置

遍历B的所有位置

如果A的位置和B的位置在同一列

输出结果

否则 继续寻找

地图可以用0-8表示A或B可能的9个位置

0------1------2

3------4------5

6------7------8

关键问题在于只使用一个变量来表示A和B的位置。所以可以使用位运算来解决。一个无符号字符类型的长度是1字节,也就是8位,8位可以表示2^8=256个值,对于A、B的9个位置来说足够。可以用前4位来表示A的位置情况,后4位表示B的位置情况。而4位可以表示16个数也足够表示A、B的位置情况了。

通过位运算可以对A、B的位置进行读取和修改。

几种基本的位运算

(1)& 按位与运算

(2)| 按位或运算 "与"和"或"就不用说了吧

(3)^ 按位异或运算 相同为假,不同为真

(4)~ 按位取反 一元运算符

(5)<< 按位左移 如 0000 0111 << 2 = 0001 1100,将此数左移两位相当于将此数扩大两倍。

(6)>> 按位右移 如 0001 1000 >> 2 = 0000 0110,将此数右移两位相当于将此数缩小两倍。

令LMASK为1111 0000,另任意一个1字节的字符型变量与其做与运算,结果右移四位,便可得到此变量的高四位的值。

Example,

0110 1011

&1111 0000

= 0110 0000 >> 4 = 0000 0110

同理,令RMASK为0000 1111,即可得到它低四位的值。

Ex.

0110 1011

& 0000 1111

= 0000 1011

设置1字节字符型变量,比如对高四位进行设置,先将变量与RMASK相与,将要修改的变量左移四位后于前一结果进行“异或”或“或运算”。

Ex.将0110 1011高四位设置为1001.

0110 1011

& 0000 1111

= 0000 1011 0000 1001 << 4 = 1001 0000

^ 1001 0000

= 1001 1011

同样的方法设置低四位的值。

代码:


这是个关于如何利用位运算解决问题的一个简单的运用,可以看到位运算合理地利用一个变量解决象棋将帅问题。算法本身很简单,重点是位运算的应用。


<BOP>上还有两个更简洁的算法:

第一个:


可以把变量i想象成一个两位九进制的变量,而i在计算机中存储的值是i的十进制表示。则i/9的计算机处理结果,即结果直接去掉小数点后部分的结果即是此九进制数的第二位,而i%9即是此九进制数的个位。本程序用此九进制数的第二位保存A的位置,个位表示B的位置。最大值为88,即为十进制的80.程序从十进制的80,即九进制的88遍历到十进制的0,即九进制的0.将符合条件的位置全部输出。


第二个:

算法与上面的如出一辙。

其中unsigned char a:4表示结构体中a的位域只有4位,高位用作它用。只能在结构体里使用,建议尽量少用,会破坏程序的移植性。

当结构体中的元素的取值范围很小时,可以将几个字段按位合成一个字段来表示,起到节省内存空间的作用。

Ex:


将上面例子中的变量i的大小输出,结果为1字节。说明i.a和i.b各占4位。

结构体是C语言中的一种常用的自定义数据结构。

看下面的例子:


按理说结构体变量i的大小应该是sizeof(int)+sizeof(char),即5,而输出显示的结果为8。再看一个例子:


应该是6对吧?结果还是8.这是为什么呢?

这是因为在32位的操作系统上,操作系统组织数据是以32位(4个字节)作为一个标准,因此各种变量的size都一般都是4的倍数。而且结构体数据都是按照定义时所使用的顺序存放的,因此在第一个例子中尽管b变量只会占有一个字节,但是a + b = 5 > 4,因此第一个4个字节存放a,第二个4个字节用于存放b,这样实际上就浪费了3个字节。在第二个例子中第二个4个字节用来存放b和c。

所以,在结构体中要注意结构体中的变量定义的顺序,不同的顺序可能会造成占用空间的不同。这在嵌入式程序设计等系统资源比较少的情况下尤为重要。比如如下两种结构体:


对于结构体m来说,x变量的大小为12,而y变量的大小为8.编译器是按程序员在结构体中声明变量的顺序处理的。不当的顺序会造成空间的浪费。读者可以想到发生这样情况的原因的。所以建议声明结构体时,按照不同变量的类型,按占用空间的大小升序或降序声明会取得较好的空间占用


分享到:
评论

相关推荐

    结构体的使用c语言练习题

    在C语言中,结构体(struct)是一种复合数据类型,它允许我们将多个不同类型的变量组合成一个新的类型。这种新类型可以包含整型、浮点型、字符型等基本类型,甚至是其他结构体类型。结构体在处理复杂数据时非常有用...

    C语言实例 字符串和结构体

    本主题聚焦于C语言中的两个核心概念:字符串和结构体,它们是C语言中非常重要的数据类型。下面将详细阐述这两个概念以及它们在实际编程中的应用。 首先,字符串在C语言中是字符数组,通常以空字符'\0'作为结束标志...

    C语言教学课件:c语言结构体.ppt

    C语言教学课件:c语言结构体.ppt

    c语言结构体

    大一c语言课程之c语言结构体。详细讲解了结构体数据类型,结构体变量的应用结构体数据类型的定义及其变量的申明和引用。

    结构体编程 C语言

    通过这两个结构体的示例,我们可以看到C语言中结构体的强大之处,它不仅能够组织和存储不同类型的数据,还能够通过简单的代码实现复杂的数据处理和分析功能。这对于任何涉及到大量数据管理的项目来说,都是非常有用...

    c语言读入文本文档到结构体.txt

    有时候不确定文本文档内有多少行数据,且数据还有表头,有行号,这些为字符串型,而内容为double型,怎样读入呢?放入结构体就好啦,真心不错

    C语言讲义(指针,结构体)

    本讲义主要聚焦于C语言中的两个关键概念:指针和结构体,它们是C语言编程的核心部分,对于理解和编写高级C程序至关重要。 一、数据类型 在C语言中,数据类型是编程的基础,它定义了变量可以存储的数据种类。常见的...

    SPT-C语言基础-结构体和结构体数组.pptx

    SPT-C语言基础-结构体和结构体数组.pptx

    <<C语言程序设计>>课件

    《C语言程序设计》是一门基础且至关重要的编程课程,尤其对于计算机科学和技术领域的学习者而言。这门课程旨在教授如何使用C语言进行程序开发,理解计算机底层工作原理,并掌握编程思维。C语言以其简洁、高效和灵活...

    c语言结构体-C语言中结构体的概念与使用方法介绍

    内容概要:本文详细介绍了C语言中的结构体概念及其用法,涵盖结构体的定义、变量声明和初始化、成员访问、结构体数组以及结构体指针的相关知识点。具体示例展示结构体作为复合数据类型,能够封装多种数据类型的优点...

    如何在C语言的结构体中像类一样封装函数

    在C语言中,尽管结构体是用来组织数据的一种方式,它本身并不支持直接在其中定义或封装函数,就像C++中的类。然而,通过巧妙地利用函数指针,我们可以模拟类的面向对象特性,实现类似的功能。下面将详细介绍如何在...

    初步剖析C语言编程中的结构体.doc

    C语言中的结构体是编程中一个非常重要的概念,它允许我们把不同类型的数据组合在一起作为一个单一的实体处理。这种数据组织方式对于创建复杂的数据结构和对象非常有用,甚至可以说是C++面向对象特性的基础,因为当...

    C语言程序设计清华大学结构体PPT课件.pptx

    在C语言中,结构体(struct)是一种非常重要的数据类型,它允许我们将不同类型的数据组合成一个整体,方便管理和操作。在清华大学的C语言程序设计课程中,结构体是核心知识点之一,主要涵盖了以下内容: 1. **概述*...

    C语言的指针使用与结构体的使用

    结构体是C语言中用于组合不同类型数据的工具,它可以封装多个变量,形成一个复合类型。使用结构体的主要步骤如下: 1. **定义结构体**:使用`struct`关键字定义一个新的类型,如`struct Person { char name[20]; ...

    C语言用结构体定义复数,实现四则运算

    C语言中没有复数运算,只有实数运行,为此,用结构体定义复数,并实现其四则运算

    学生成绩管理程序-结构体数组法.rar

    结构体是C语言中的复合数据类型,可以定义一个新的数据类型,该类型包含不同类型的成员。例如,我们可以定义一个名为`Student`的结构体,包括学生的姓名、学号、年龄和各科成绩等字段。定义结构体的基本语法是: `...

    java 与C语言使用socket通信传递结构体数据

    C语言中的结构体是一种自定义的数据类型,它允许我们将多个不同类型的数据项组合成一个复合实体。例如,假设我们有一个C语言的结构体如下: ```c struct Person { char name[20]; int age; float height; }; ```...

    C语言 结构体范例代码

    在C语言中,结构体(struct)是一种复合数据类型,它允许我们将多个不同类型的变量组合成一个单一的实体。这使得我们能够创建更复杂的数据结构,以更好地模拟现实世界中的对象或概念。以下是对“C语言 结构体范例...

    C语言结构体实现方法

    在C语言中,结构体(struct)是一种复合数据类型,它允许我们将多个不同类型的变量组合成一个单一的实体。这使得我们能够以更模块化和组织化的方式处理数据。本篇将详细介绍C语言中结构体的实现方法以及规范的编码...

Global site tag (gtag.js) - Google Analytics