使用“char”的布尔数组
我创建了一个对象,它实际上表示存储在 char 中的 8 个布尔值的数组。我这样做是为了更多地了解按位运算符以及在 C 中创建自己的对象。所以我有两个问题:
- 我可以确定下面的代码是否 总是有效吗?
- 这是一个很好的实施吗 制作一个不会丢失的物品 在C中,除非你释放它 你自己。
代码:
/*
* IEFBooleanArray.h
* IEFBooleanArray
*
* Created by ief2 on 8/08/10.
* Copyright 2010 ief2. All rights reserved.
*
*/
#ifndef IEFBOOLEANARRAY_H
#define IEFBOOLEANARRAY_H
#include <stdlib.h>
#include <string.h>
#include <math.h>
typedef char * IEFBooleanArrayRef;
void IEFBooleanArrayCreate(IEFBooleanArrayRef *ref);
void IEFBooleanArrayRelease(IEFBooleanArrayRef ref);
int IEFBooleanArraySetBitAtIndex(IEFBooleanArrayRef ref,
unsigned index,
int flag);
int IEFBooleanArrayGetBitAtIndex(IEFBooleanArrayRef ref,
unsigned index);
#endif
/*
* IEFBooleanArray.c
* IEFBooleanArray
*
* Created by ief2 on 8/08/10.
* Copyright 2010 ief2. All rights reserved.
*
*/
#include "IEFBooleanArray.h"
void IEFBooleanArrayCreate(IEFBooleanArrayRef *ref) {
IEFBooleanArrayRef newReference;
newReference = malloc(sizeof(char));
memset(newReference, 0, sizeof(char));
*ref = newReference;
}
void IEFBooleanArrayRelease(IEFBooleanArrayRef ref) {
free(ref);
}
int IEFBooleanArraySetBitAtIndex(IEFBooleanArrayRef ref, unsigned index, int flag) {
int orignalStatus;
if(index < 0 || index > 7)
return -1;
if(flag == 0)
flag = 0;
else
flag = 1;
orignalStatus = IEFBooleanArrayGetBitAtIndex(ref, index);
if(orignalStatus == 0 && flag == 1)
*ref = *ref + (int)pow(2, index);
else if(orignalStatus == 1 && flag == 0)
*ref = *ref - (int)pow(2, index);
return 0;
}
int IEFBooleanArrayGetBitAtIndex(IEFBooleanArrayRef ref, unsigned index) {
int result;
int value;
value = (int)pow(2, index);
result = value & *ref;
if(result == 0)
return 0;
else
return 1;
}
我更喜欢 Objective-C,但我真的想更多地学习 C。有人可以要求我多做一些“作业”来提高自己吗?
谢谢你, IEF2
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
至于访问 char 对象中的位 #n,您可以使用移位和屏蔽来代替使用 pow() 函数:
设置位 #n:
清除位 #n:
获取位 #n:
As for accessing bit #n in your char object, instead of using pow() function, you can use shifting and masking:
Set bit #n:
Clear bit #n:
Get bit #n:
似乎没有人提到这一点(我很惊讶),但是......你不能告诉我你正在认真地做
malloc(sizeof(char))
吗?这是一个非常小的分配。将其设为堆分配对象是没有意义的。只需将其声明为char
即可。如果您想要某种程度的封装,可以执行以下操作:
typedef char IEFBoolArray;
并创建访问器函数来操作IEFBoolArray
。或者甚至执行 typedef struct { char value; } IEFBoolArray; 但是考虑到数据的大小,在堆上一次分配这些数据简直就是疯狂。让该类型的使用者只需将其声明为内联并使用访问器即可。此外...您确定要它是
char
吗?如果将其提升为更大的代码(例如int
),您可能会生成稍微更好的代码。Nobody seems to be mentioning this (I am surprised), but... You can't tell me you're seriously doing
malloc(sizeof(char))
? That is a very small allocation. It doesn't make sense to make this a heap allocated object. Just declare it aschar
.If you want to have some degree of encapsulation, you can do:
typedef char IEFBoolArray;
and make accessor functions to manipulate anIEFBoolArray
. Or even dotypedef struct { char value; } IEFBoolArray;
But given the size of the data it would be sheer madness to allocate these one at a time on the heap. Have consumers of the type just declare it inline and use the accessors.Further... Are you sure you want it to be
char
? You might get slightly better code generated if you promote that to something larger, likeint
.除了 Carl Norum 的观点之外:
从第三点开始,类似:
实际上并非如此。您自愿发布它们在cc-by-sa 许可,仅保留部分权利。此外,您希望我们阅读并修改代码,因此保留所有权利是没有意义的。
(PS。无论如何,我建议不要在限制性许可下发布琐碎的作品 - 它看起来不看起来很专业 - 除非你这样做有法律问题)
对不起?
In addition to Carl Norum points:
As of 3rd point something like:
Actually they are not. You volontarly published them under cc-by-sa licence and only some right are reserved. Additionally you want us to read and modify the code so reserving all right is pointless.
(PS. I would advice against publishing trivial work under restrictive licences anyway - it does not look professionaly - unless you have legal issues to do so)
Sorry?
< 检查无符号类型0
,它没有意义,并且会在某些编译器上引起警告。unsigned int
、unsigned char
等)。flag == 0
为什么要将其设置为0
?typedef
中抽象出*
,但无论如何这都没有错误。memset()
将单个字节设置为0
。pow
来计算位偏移量是疯狂的。查看<<
和>>
运算符并使用它们,将if
语句条件完全放在括号中,或者准备好调试痛苦在你的未来。SetBitAtIndex 中使用按位运算符
函数,无论如何你都不需要所有那些复杂的&
和|
而不是算术+
和-
if
语句。GetBitAtIndex
例程不会对index
进行边界检查。我认为,从该列表中,#9 是唯一一个意味着您的程序无法在所有情况下运行的选项。我没有对其进行详尽的测试——这只是初步检查。
< 0
, it's meaningless and causes warnings on some compilers.unsigned int
,unsigned char
, etc).flag == 0
why are you setting it to0
?*
away in atypedef
, but it's not wrong by any means.memset()
to set a single byte to0
.pow
to calculate a bit offset is crazy. Check out the<<
and>>
operators and use those insteadif
statement conditions or be prepared for debugging pain in your future.&
and|
instead of arithmetic+
and-
in yourSetBitAtIndex
function, you won't need all those complicatedif
statements anyway.GetBitAtIndex
routine doesn't bounds checkindex
.From that list, #9 is the only one that means your program won't work in all cases, I think. I didn't exhaustively test it - that's just a first glance check.
pow(2,index)
是生成位掩码的效率较低的方法之一。我可以想象使用 Ackermann 函数可能会更糟,但是pow()
速度相当慢。您应该使用(1< 代替。此外,设置/清除值中的位的 C'ish 方式看起来有所不同。这是最近的一个与此相关的问题:
如果你想以一种高效且可移植的方式在 C 中处理位,那么你真的应该看看 bit twiddling 页面,如果你提到的话,这里的每个人都会向你推荐“位”不知何故:
以下代码序列:
可以写成
return (result != 0);
、return result
或return !!result
(如果结果应强制为 0 或 1)。尽管明确意图总是一个好主意,但大多数 C 程序员更喜欢“结果结果”;因为在 C 语言中这是明确意图的方式。 if 看起来很可疑,就像一个警告贴纸,上面写着“原始开发人员是 Java 人员,对位了解不多”之类的。malloc + memset(x,0,z) == calloc();
您可以为
IEFBooleanArraySetBitAtIndex
报告错误(无效索引),但不能< /strong> 代表IEFBooleanArrayGetBitAtIndex
。这是不一致的。使错误报告统一,否则库的用户将搞砸错误检查。pow(2,index)
is among the more inefficient ways to produce a bit mask. I can imagine that using the Ackermann function could be worse, butpow()
is pretty much on the slow side. You should use(1<<index)
instead. Also, the C'ish way to set/clear a bit in a value looks different. Here's a recent question about this:If you want to munge bits in C in an efficient and portable way, then you really should have a look at the bit twiddling page, that everyone here will suggest to you if you mention "bits" somehow:
The following code sequence:
can be written as
return (result != 0);
,return result
orreturn !!result
(if result should be forced to 0 or 1) . Though it's always a good idea to make an intent clear, most C programmer will prefer 'result result;' because in C this the way to make your intent clear. The if looks iffy, like a warning sticker saying "Original developer is a Java guy and knows not much about bits" or something.malloc + memset(x,0,z) == calloc();
You have a way to report an error (invalid index) for
IEFBooleanArraySetBitAtIndex
but not forIEFBooleanArrayGetBitAtIndex
. This is inconsistent. Make error reporting uniform, or the users of your library will botch error checking.