lua程序设计(第四版)练习答案自做(第三十一章)

31.1

#include <stdarg.h>
#include <stdlib.h>
#include <lua.h>
#include <lauxlib.h>
#include <limits.h>
#define BITS_PER_WORD (CHAR_BIT*sizeof(unsigned int))
#define I_WORD(i) ((unsigned int)(i)/BITS_PER_WORD)
#define I_BIT(i) (1<<((unsigned int)(i)%BITS_PER_WORD))
#define checkarray(L) (BitArray *)luaL_checkudata(L,1,"LuaBook.array");
typedef struct BitArray
{
	int size;
	unsigned int values[1];
}BitArray;
static void error(lua_State *L,const char *fmt,...)
{
	va_list argp;
	va_start(argp,fmt);
	vfprintf(stderr,fmt,argp);
	va_end(argp);
	exit(EXIT_FAILURE);
}
static unsigned int *getparams(lua_State *L,unsigned int *mask)
{
	BitArray *a=checkarray(L);
	int index=(int)luaL_checkinteger(L,2)-1;
	luaL_argcheck(L,0<=index&&index<a->size,2,"index out of range");
	*mask=I_BIT(index);
	return &a->values[I_WORD(index)];
}
static int array2string(lua_State *L)
{
	BitArray *a=checkarray(L);
	lua_pushfstring(L,"array(%d)",a->size);
	return 1;
}
static int newarray(lua_State *L)
{
	int i;
	size_t nbytes;
	BitArray *a;
	int n=(int)luaL_checkinteger(L,1);
	luaL_argcheck(L,n>=1,1,"invalid size");
	nbytes=sizeof(BitArray)+I_WORD(n-1)*sizeof(unsigned int);
	a=(BitArray *)lua_newuserdata(L,nbytes);
	a->size=n;
	for(i=0;i<=I_WORD(n-1);i++)
		a->values[i]=0;
	luaL_getmetatable(L,"LuaBook.array");
	lua_setmetatable(L,-2);
	return 1;
}
static int setarray(lua_State *L)
{
	unsigned int mask;
	unsigned int *entry;
	entry=getparams(L,&mask);
	if(!lua_isboolean(L,3))
		error(L,"need boolean for the third parameter");
	if(lua_toboolean(L,3))
		*entry|=mask;
	else
		*entry&=~mask;
	return 0;
}
static int getarray(lua_State *L)
{
	unsigned int mask;
	unsigned int *entry;
	entry=getparams(L,&mask);
	lua_pushboolean(L,*entry&mask);
	return 1;
}
static int getsize(lua_State *L)
{
	BitArray *a=checkarray(L);
	lua_pushinteger(L,a->size);
	return 1;
}
static const struct luaL_Reg arraylib_m[]=
{
	{"__newindex",setarray},
	{"__index",getarray},
	{"__len",getsize},
	{"__tostring",array2string},
	{NULL,NULL}
};
static const struct luaL_Reg arraylib_f[]=
{
	{"new",newarray},
	{NULL,NULL}
};
int luaopen_array(lua_State *L)
{
	luaL_newmetatable(L,"LuaBook.array");
	lua_pushvalue(L,-1);
	lua_setfield(L,-2,"__index");
	luaL_setfuncs(L,arraylib_m,0);
	luaL_newlib(L,arraylib_f);
	return 1;
}

31.2和31.3

#include <stdarg.h>
#include <stdlib.h>
#include <lua.h>
#include <lauxlib.h>
#include <limits.h>
#define BITS_PER_WORD (CHAR_BIT*sizeof(unsigned int))
#define I_WORD(i) ((unsigned int)(i)/BITS_PER_WORD)
#define I_BIT(i) (1<<((unsigned int)(i)%BITS_PER_WORD))
#define checkarray(L) (BitArray *)luaL_checkudata(L,1,"LuaBook.array");
typedef struct BitArray
{
	int size;
	unsigned int values[1];
}BitArray;
static void error(lua_State *L,const char *fmt,...)
{
	va_list argp;
	va_start(argp,fmt);
	vfprintf(stderr,fmt,argp);
	va_end(argp);
	exit(EXIT_FAILURE);
}
static unsigned int *getparams(lua_State *L,unsigned int *mask)
{
	BitArray *a=checkarray(L);
	int index=(int)luaL_checkinteger(L,2)-1;
	luaL_argcheck(L,0<=index&&index<a->size,2,"index out of range");
	*mask=I_BIT(index);
	return &a->values[I_WORD(index)];
}
static int array2string(lua_State *L)
{
	BitArray *a=checkarray(L);
	lua_pushfstring(L,"array(%d)",a->size);
	return 1;
}
static int newarray(lua_State *L)
{
	int i;
	size_t nbytes;
	BitArray *a;
	int n=(int)luaL_checkinteger(L,1);
	luaL_argcheck(L,n>=1,1,"invalid size");
	nbytes=sizeof(BitArray)+I_WORD(n-1)*sizeof(unsigned int);
	a=(BitArray *)lua_newuserdata(L,nbytes);
	a->size=n;
	for(i=0;i<=I_WORD(n-1);i++)
		a->values[i]=0;
	luaL_getmetatable(L,"LuaBook.array");
	lua_setmetatable(L,-2);
	return 1;
}
static int setarray(lua_State *L)
{
	unsigned int mask;
	unsigned int *entry;
	entry=getparams(L,&mask);
	if(!lua_isboolean(L,3))
		error(L,"need boolean for the third parameter\n");
	if(lua_toboolean(L,3))
		*entry|=mask;
	else
		*entry&=~mask;
	return 0;
}
static int getarray(lua_State *L)
{
	unsigned int mask;
	unsigned int *entry;
	entry=getparams(L,&mask);
	lua_pushboolean(L,*entry&mask);
	return 1;
}
static int getsize(lua_State *L)
{
	BitArray *a=checkarray(L);
	lua_pushinteger(L,a->size);
	return 1;
}
static int arrayunion(lua_State *L)
{
	int index;
	int flag_x,flag_y,mask;
	BitArray *a,*x,*y;
	size_t nbytes;
	x=(BitArray *)luaL_checkudata(L,1,"LuaBook.array");
	y=(BitArray *)luaL_checkudata(L,2,"LuaBook.array");
	int n=(x->size>y->size?x->size:y->size);
	nbytes=sizeof(BitArray)+I_WORD(n-1)*sizeof(unsigned int);
	a=(BitArray *)lua_newuserdata(L,nbytes);
	a->size=n;
	for(index=0;index<=I_WORD(n-1);index++)
	{
		a->values[index]=0;
	}
	for(index=0;index<(x->size<y->size?x->size:y->size);index++)
	{
		mask=I_BIT(index);
		flag_x=x->values[I_WORD(index)]&mask;
		flag_y=y->values[I_WORD(index)]&mask;
		if(flag_x|flag_y)
			a->values[I_WORD(index)]|=mask;
		else
			a->values[I_WORD(index)]&=~mask;
	}
	luaL_getmetatable(L,"LuaBook.array");
	lua_setmetatable(L,-2);
	return 1;
}
static int arrayintersection(lua_State *L)
{
	int index;
	BitArray *a,*x,*y;
	size_t nbytes;
	x=(BitArray *)luaL_checkudata(L,1,"LuaBook.array");
	y=(BitArray *)luaL_checkudata(L,2,"LuaBook.array");
	int n=(x->size>y->size?x->size:y->size);
	nbytes=sizeof(BitArray)+I_WORD(n-1)*sizeof(unsigned int);
	a=(BitArray *)lua_newuserdata(L,nbytes);
	a->size=n;
	for(index=0;index<=I_WORD(n-1);index++)
	{
		a->values[index]=0;
	}

	n=(x->size<y->size?x->size:y->size);
	for(index=0;index<=I_WORD(n-1);index++)
	{
		a->values[index]=x->values[index]&y->values[index];
	}
	luaL_getmetatable(L,"LuaBook.array");
	lua_setmetatable(L,-2);
	return 1;
}
static const struct luaL_Reg arraylib_m[]=
{
	{"__newindex",setarray},
	{"__index",getarray},
	{"__len",getsize},
	{"__tostring",array2string},
	{"__add",arrayunion},
	{"__mul",arrayintersection},
	{NULL,NULL}
};
static const struct luaL_Reg arraylib_f[]=
{
	{"new",newarray},
	{NULL,NULL}
};
int luaopen_array(lua_State *L)
{
	luaL_newmetatable(L,"LuaBook.array");
	lua_pushvalue(L,-1);
	lua_setfield(L,-2,"__index");
	luaL_setfuncs(L,arraylib_m,0);
	luaL_newlib(L,arraylib_f);
	return 1;
}

31.4

#include <stdarg.h>
#include <stdlib.h>
#include <lua.h>
#include <lauxlib.h>
#include <limits.h>
#define BITS_PER_WORD (CHAR_BIT*sizeof(unsigned int))
#define I_WORD(i) ((unsigned int)(i)/BITS_PER_WORD)
#define I_BIT(i) (1<<((unsigned int)(i)%BITS_PER_WORD))
#define checkarray(L) (BitArray *)luaL_checkudata(L,1,"LuaBook.array");
typedef struct BitArray
{
	int size;
	unsigned int values[1];
}BitArray;
static void error(lua_State *L,const char *fmt,...)
{
	va_list argp;
	va_start(argp,fmt);
	vfprintf(stderr,fmt,argp);
	va_end(argp);
	exit(EXIT_FAILURE);
}
static unsigned int *getparams(lua_State *L,unsigned int *mask)
{
	BitArray *a=checkarray(L);
	int index=(int)luaL_checkinteger(L,2)-1;
	luaL_argcheck(L,0<=index&&index<a->size,2,"index out of range");
	*mask=I_BIT(index);
	return &a->values[I_WORD(index)];
}
static int array2string(lua_State *L)
{
	int index;
	luaL_Buffer b;
	luaL_buffinit(L,&b);
	BitArray *a=checkarray(L);
	lua_pushfstring(L,"array(%d)",a->size);
	luaL_addvalue(&b);
	for(index=0;index<a->size;index++)
	{
		if(a->values[I_WORD(index)]&I_BIT(index))
		{
			lua_pushfstring(L," array[%d]=true",index);
			luaL_addvalue(&b);
		}
		else
		{
			lua_pushfstring(L," array[%d]=false",index);
			luaL_addvalue(&b);
		}
	}
	luaL_pushresult(&b);
	return 1;
}
static int newarray(lua_State *L)
{
	int i;
	size_t nbytes;
	BitArray *a;
	int n=(int)luaL_checkinteger(L,1);
	luaL_argcheck(L,n>=1,1,"invalid size");
	nbytes=sizeof(BitArray)+I_WORD(n-1)*sizeof(unsigned int);
	a=(BitArray *)lua_newuserdata(L,nbytes);
	a->size=n;
	for(i=0;i<=I_WORD(n-1);i++)
		a->values[i]=0;
	luaL_getmetatable(L,"LuaBook.array");
	lua_setmetatable(L,-2);
	return 1;
}
static int setarray(lua_State *L)
{
	unsigned int mask;
	unsigned int *entry;
	entry=getparams(L,&mask);
	if(!lua_isboolean(L,3))
		error(L,"need boolean for the third parameter\n");
	if(lua_toboolean(L,3))
		*entry|=mask;
	else
		*entry&=~mask;
	return 0;
}
static int getarray(lua_State *L)
{
	unsigned int mask;
	unsigned int *entry;
	entry=getparams(L,&mask);
	lua_pushboolean(L,*entry&mask);
	return 1;
}
static int getsize(lua_State *L)
{
	BitArray *a=checkarray(L);
	lua_pushinteger(L,a->size);
	return 1;
}
static int arrayunion(lua_State *L)
{
	int index;
	int flag_x,flag_y,mask;
	BitArray *a,*x,*y;
	size_t nbytes;
	x=(BitArray *)luaL_checkudata(L,1,"LuaBook.array");
	y=(BitArray *)luaL_checkudata(L,2,"LuaBook.array");
	int n=(x->size>y->size?x->size:y->size);
	nbytes=sizeof(BitArray)+I_WORD(n-1)*sizeof(unsigned int);
	a=(BitArray *)lua_newuserdata(L,nbytes);
	a->size=n;
	for(index=0;index<=I_WORD(n-1);index++)
	{
		a->values[index]=0;
	}
	for(index=0;index<(x->size<y->size?x->size:y->size);index++)
	{
		mask=I_BIT(index);
		flag_x=x->values[I_WORD(index)]&mask;
		flag_y=y->values[I_WORD(index)]&mask;
		if(flag_x|flag_y)
			a->values[I_WORD(index)]|=mask;
		else
			a->values[I_WORD(index)]&=~mask;
	}
	luaL_getmetatable(L,"LuaBook.array");
	lua_setmetatable(L,-2);
	return 1;
}
static int arrayintersection(lua_State *L)
{
	int index;
	BitArray *a,*x,*y;
	size_t nbytes;
	x=(BitArray *)luaL_checkudata(L,1,"LuaBook.array");
	y=(BitArray *)luaL_checkudata(L,2,"LuaBook.array");
	int n=(x->size>y->size?x->size:y->size);
	nbytes=sizeof(BitArray)+I_WORD(n-1)*sizeof(unsigned int);
	a=(BitArray *)lua_newuserdata(L,nbytes);
	a->size=n;
	for(index=0;index<=I_WORD(n-1);index++)
	{
		a->values[index]=0;
	}

	n=(x->size<y->size?x->size:y->size);
	for(index=0;index<=I_WORD(n-1);index++)
	{
		a->values[index]=x->values[index]&y->values[index];
	}
	luaL_getmetatable(L,"LuaBook.array");
	lua_setmetatable(L,-2);
	return 1;
}
static const struct luaL_Reg arraylib_m[]=
{
	{"__newindex",setarray},
	{"__index",getarray},
	{"__len",getsize},
	{"__tostring",array2string},
	{"__add",arrayunion},
	{"__mul",arrayintersection},
	{NULL,NULL}
};
static const struct luaL_Reg arraylib_f[]=
{
	{"new",newarray},
	{NULL,NULL}
};
int luaopen_array(lua_State *L)
{
	luaL_newmetatable(L,"LuaBook.array");
	lua_pushvalue(L,-1);
	lua_setfield(L,-2,"__index");
	luaL_setfuncs(L,arraylib_m,0);
	luaL_newlib(L,arraylib_f);
	return 1;
}

31.5

#include <stdarg.h>
#include <stdlib.h>
#include <lua.h>
#include <lauxlib.h>
#include <limits.h>
#define checkarray(L) (IntArray *)luaL_checkudata(L,1,"LuaInt.array");
typedef struct IntArray
{
	int size;
	int values[1];
}IntArray;
static void error(lua_State *L,const char *fmt,...)
{
	va_list argp;
	va_start(argp,fmt);
	vfprintf(stderr,fmt,argp);
	va_end(argp);
	exit(EXIT_FAILURE);
}
static int *getparams(lua_State *L)
{
	IntArray *a=checkarray(L);
	int index=(int)luaL_checkinteger(L,2)-1;
	luaL_argcheck(L,0<=index&&index<a->size,2,"index out of range");
	return &a->values[index];
}

static int array2string(lua_State *L)
{
	int index;
	luaL_Buffer b;
	luaL_buffinit(L,&b);
	IntArray *a=checkarray(L);
	lua_pushfstring(L,"array(%d)",a->size);
	luaL_addvalue(&b);
	for(index=0;index<a->size;index++)
	{
		lua_pushfstring(L," array[%d]=%d",index,a->values[index]);
		luaL_addvalue(&b);
	}
	luaL_pushresult(&b);
	return 1;
}

static int newarray(lua_State *L)
{
	int i;
	size_t nbytes;
	IntArray *a;
	int n=(int)luaL_checkinteger(L,1);
	luaL_argcheck(L,n>=1,1,"invalid size");
	nbytes=sizeof(IntArray)+(n-1)*sizeof(int);
	a=(IntArray *)lua_newuserdata(L,nbytes);
	a->size=n;
	for(i=0;i<n;i++)
		a->values[i]=0;
	luaL_getmetatable(L,"LuaInt.array");
	lua_setmetatable(L,-2);
	return 1;
}
static int setarray(lua_State *L)
{
	int *entry;
	entry=getparams(L);
	*entry=(int)luaL_checkinteger(L,3);
	return 0;
}
static int getarray(lua_State *L)
{
	int *entry;
	entry=getparams(L);
	lua_pushinteger(L,*entry);
	return 1;
}
static int getsize(lua_State *L)
{
	IntArray *a=checkarray(L);
	lua_pushinteger(L,a->size);
	return 1;
}
static const struct luaL_Reg arraylib_m[]=
{
	{"__newindex",setarray},
	{"__index",getarray},
	{"__len",getsize},
	{"__tostring",array2string},
	{NULL,NULL}
};
static const struct luaL_Reg arraylib_f[]=
{
	{"new",newarray},
	{NULL,NULL}
};
int luaopen_array(lua_State *L)
{
	luaL_newmetatable(L,"LuaInt.array");
	lua_pushvalue(L,-1);
	lua_setfield(L,-2,"__index");
	luaL_setfuncs(L,arraylib_m,0);
	luaL_newlib(L,arraylib_f);
	return 1;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值