记得结构体可以用某种方法隐藏变量(例如struct Student{int:10};这样匿名声明)~
然后按照这个题目来做一个关于获取隐藏参数信息的,最近看了一下数据库,这可以算是一个小型的数据管理结构模式了~
而且这还是相对于处理单1个学生的情况,其实改改也可以多个,但由于具体实现结构会使结构体Student里面的参数有冗余,所以这只是对一个学生对象操作比较合适,有兴趣的可以看看获取匿名变量的方法
~
程序代码:
#include <stdio.h>
#include<stdlib.h>
#include<string.h>
#include<limits.h>
#include<stdarg.h>
#include<assert.h>
#pragma pack (1)
#define __OK 0
#define __ERROR 1
#define __EFAULT 2
#define __UN_INIT 3
#ifndef IS_ERR
#define IS_ERR(E,RET) \
do \
{ \
if (E) \
return RET; \
}while (0)
#endif
#ifndef INT_BIT
#define INT_BIT \
(sizeof ( int )*CHAR_BIT)
#endif
#define __PARA_LIST( S ) \
((( int* )(S)+1))
#define __PARA_NUM_ID( S,N ) \
(( int* )(( int* )(*__PARA_LIST(S))+(N)-1))
#define __PARA_ID( S,N ) \
( ( char* )(__PARA_LIST(S)+1)+*__PARA_NUM_ID((S),(N)))
#define __PARA_DATA( S ,N,TYPE ) \
(*(( TYPE* )__PARA_ID((S),(N))))
void nodeMal( void**,size_t );
void nodeFree( void** );
typedef int Status;
typedef struct Student Student;
typedef const struct Stu_Metion Stu_Metion;
typedef struct Information Information;
static void _Init_Student( size_t,Student**,... );
Status newStudent( const Information*,Student** );
Status setScore( const Student* );
Status getScore( const Student*,unsigned char* );
Status printLevel( const Student* );
Status dropStu( Student** );
struct Student
{
#define __PARA_LEN int
#define __PARA_LOCATION int
#define __STATUS int
#define __INF int
#define __LEVEL int
#define __SCORE int
__PARA_LEN: INT_BIT;
__PARA_LOCATION: INT_BIT;
__STATUS: INT_BIT;
__INF: INT_BIT;
__SCORE: CHAR_BIT;
__LEVEL: INT_BIT;
#undef __PARA_LEN
#undef __PARA_LOCATION
#undef __STATUS
#undef __INF
#undef __SCORE
#undef __LEVEL
};
const struct Stu_Metion
{
Status (*newStudent)( const Information*,Student** );
Status ( *setScore)( const Student* );
Status ( *getScore )(const Student*,unsigned char* );
Status ( *printLevel)( const Student* );
Status ( *dropStu)( Student** );
}stu_metion=
{
newStudent,
setScore,
getScore,
printLevel,
dropStu
};
struct Information
{
const char* inf[6];
Student* stu;
const Stu_Metion const* metion;
}stu_inf=
{
{"满分","优","良","好","合格","挂科"},
NULL,
&stu_metion
};
int main( void )
{
const Stu_Metion* const metion=stu_inf.metion;
Student**const stu=&stu_inf.stu;
unsigned char score;
if (metion->newStudent(&stu_inf,stu))
{
puts("分配空间没有实现!");
metion->dropStu(stu);
exit(EXIT_FAILURE);
}
if (metion->setScore(*stu))
{
puts("成绩输入错误!");
metion->dropStu(stu);
exit(EXIT_FAILURE);
}
metion->getScore(*stu,&score);
printf("学生成绩已成功读取,为:%hhu\n",score);
metion->printLevel(*stu);
metion->dropStu(stu);
return 0;
}
void nodeMal( void** p,size_t size )
{
assert(p);
*p=malloc(size);
assert(*p);
memset(*p,0,size);
}
void nodeFree( void** p )
{
assert(p);
free(*p);
*p=NULL;
}
static void _Init_Student( size_t len,Student** stu,... )
{
va_list ap;
int** p_list=NULL;
int* p=NULL;
unsigned count=8;
size_t i;
va_start(ap,stu);
for (i=0;i!=len;++i)
count+=va_arg(ap,int)/CHAR_BIT;
nodeMal(( void** )stu,sizeof (Student)+count);
IS_ERR(!*stu,__EFAULT);
p_list=( int** )__PARA_LIST(*stu);
nodeMal(( void** )p_list,(len+1)*sizeof (unsigned));
IS_ERR(!*p_list,__EFAULT);
va_start(ap,stu);
count=0;
for (p=*p_list;p!=*p_list+len;++p)
{
*p=count/CHAR_BIT;
count+=va_arg(ap,int);
}
*p=count/CHAR_BIT;
va_end(ap);
}
Status newStudent( const Information* stu_inf,Student** stu )
{
IS_ERR(!stu,__EFAULT);
_Init_Student(4,stu,INT_BIT,INT_BIT,CHAR_BIT,INT_BIT);
IS_ERR(!*stu,__EFAULT);
__PARA_DATA(*stu,1,Status)=__UN_INIT;
__PARA_DATA(*stu,2,const Information*)=stu_inf;
return __OK;
}
Status setScore( const Student* stu )
{
const Information* stu_inf=NULL;
const Information t_inf;
const size_t len=sizeof (t_inf.inf)/sizeof (*t_inf.inf);
unsigned score;
int c;
IS_ERR(!stu,__EFAULT);
puts("请输入学生成绩:");
if (scanf("%u",&score)!=1||score>100)
{
while ((c=getchar())!=EOF&&c!='\n');
__PARA_DATA(stu,1,Status)=__ERROR;
return __ERROR;
}
while ((c=getchar())!=EOF&&c!='\n');
stu_inf=__PARA_DATA(stu,2,Information*);
__PARA_DATA(stu,4,const char*)=(score>59?*(stu_inf->inf+10-(score/10)):*(stu_inf->inf+len-1));
__PARA_DATA(stu,3,unsigned char )=score;
return __PARA_DATA(stu,1,Status)=__OK;
}
#define __IS_DATA_ERR( stu ) \
do \
{ \
IS_ERR(!(stu),__EFAULT); \
{ \
const Status __STU_COM=__PARA_DATA((stu),1,Status); \
\
IS_ERR(__STU_COM,__STU_COM); \
} \
}while (0)
Status getScore( const Student* stu,unsigned char* score )
{
__IS_DATA_ERR(stu);
*score=__PARA_DATA(stu,3,unsigned char);
return __OK;
}
Status printLevel( const Student* stu )
{
__IS_DATA_ERR(stu);
printf("评价等级为:%s\n",__PARA_DATA(stu,4,const char*));
return __OK;
}
#undef __IS_DATA_ERR
Status dropStu( Student** stu )
{
IS_ERR(!stu,__EFAULT);
IS_ERR(!*stu,__EFAULT);
{
void** stu_list=( void* )__PARA_LIST(*stu);
nodeFree(stu_list);
nodeFree(( void** )stu);
}
return __OK;
}
2017-04-17-00-00更~
原来之前发现sizeof (Student)=0;也就是说匿名结构体成员sizeof检索不了,或者说是把分配的空间隐藏起来了,找了很久bug发现是因为分配空间问题从而对"越界部分"写入数据,结果因为系统数据更新修改该储存值而出问题了,这个是值得注意的,现在改好了,可以用了
~
[此贴子已经被作者于2018-4-17 00:24编辑过]