当前位置: 首页 > news >正文

网站建设方案评标原则小榄网站建设推广

网站建设方案评标原则,小榄网站建设推广,亚马逊站外推广网站,长春快速建站公司《C Primer Plus》#xff08;第6版#xff09;第13章编程练习《C Primer Plus》#xff08;第6版#xff09;第13章编程练习1. Cd类2. 使用动态内存分配重做练习13. baseDMA、lacksDMA、hasDMA类4. Port类和VintagePort类《C Primer Plus》#xff08;第6版#xff09;第… 《C Primer Plus》第6版第13章编程练习《C Primer Plus》第6版第13章编程练习1. Cd类2. 使用动态内存分配重做练习13. baseDMA、lacksDMA、hasDMA类4. Port类和VintagePort类《C Primer Plus》第6版第13章编程练习 1. Cd类 以下面的类声明为基础 class Cd { //represents a CD disk private:char performers[50];char label[20];int selections; //number of selectionsdouble playtime; //playing time in minute public:Cd(char* s1, char* s2, int n, double x);Cd(const Cd d);Cd();~Cd();void Report() const; //reports all CD dataCd operator(const Cd d); };派生出一个Classic类并添加一组char成员用于存储指出CD中主要作品的字符串。修改上述声明使基类的搜有函数都是虚的。如果上述定义声明的某个方法并不需要则请删除它。使用下面的程序测试您的产品 #includeiostream using namespace std; #includeclassic.hvoid Bravo(const Cd disk);int main() {Cd c1(beatles, Capitol, 14, 35.5);Classic c2 Classic(Piano Sonata in B flat, Fantasia in C, Alfred Brendel, Philips, 2, 57.17);Cd* pcd c1;cout Using object directly:\n;c1.Report(); //use Cd methodc2.Report(); //use Classic methodcout Using type cd *pointer to objects:\n;pcd-Report(); //use Cd method for cd objectpcd c2;pcd-Report(); //use Classic method for classic objectcout Calling a function with a Cd reference argument:\n;Bravo(c1);Bravo(c2);cout Testing assignment: ;Classic copy;copy c2;copy.Report();return 0; }void Bravo(const Cd disk) {disk.Report(); }代码 cd.h #ifndef CD_H_ #define CD_H_class Cd { // represents a CD disk private:char performers[50];char label[20];int selections; // number of selectionsdouble playtime; // playing time in minutepublic:Cd(char *s1, char *s2, int n, double x);Cd(const Cd d);Cd();virtual ~Cd();virtual void Report() const; // reports all CD datavirtual Cd operator(const Cd d); };#endifcd.cpp #include cd.h #include iostream #include cstringCd::Cd(char *s1, char *s2, int n, double x) {strncpy(performers, s1, 49);performers[49] \0;strncpy(label, s2, 19);label[19] \0;selections n;playtime x; } Cd::Cd(const Cd d) {strncpy(performers, d.performers, 49);performers[49] \0;strncpy(label, d.label, 19);label[19] \0;selections d.selections;playtime d.playtime; } Cd::Cd() {performers[0] \0;label[0] \0;selections 0;playtime 0.0; } Cd::~Cd() { } void Cd::Report() const {using std::cout;using std::endl;cout Information:\n;cout Performers: performers endl;cout Label: label endl;cout Selections: selections endl;cout Playtime: playtime endl; } Cd Cd::operator(const Cd d) {if (this d)return *this;strncpy(performers, d.performers, 49);performers[49] \0;strncpy(label, d.label, 19);label[19] \0;selections d.selections;playtime d.playtime;return *this; }classic.h #ifndef CLASSIC_H_ #define CLASSIC_H_#include cd.hclass Classic : public Cd { private:char majorWorks[50];public:Classic(char *m, char *s1, char *s2, int n, double x);Classic(char *m, const Cd cd);Classic();virtual ~Classic();virtual void Report() const;virtual Classic operator(const Classic c); };#endifclassic.cpp #include classic.h #include iostream #include cstringClassic::Classic(char *m, char *s1, char *s2, int n, double x) : Cd(s1, s2, n, x) {strncpy(majorWorks, m, 49);majorWorks[49] \0; } Classic::Classic(char *m, const Cd cd) : Cd(cd) {strncpy(majorWorks, m, 49);majorWorks[49] \0; } Classic::Classic() : Cd() {majorWorks[0] \0; } Classic::~Classic() { } void Classic::Report() const {using std::cout;using std::endl;Cd::Report();cout Major works: majorWorks endl; } Classic Classic::operator(const Classic c) {if (this c)return *this;Cd::operator(c);strncpy(majorWorks, c.majorWorks, 49);majorWorks[49] \0;return *this; }main.cpp #include iostream using namespace std; #include classic.hvoid Bravo(const Cd disk);int main() {Cd c1(beatles, Capitol, 14, 35.5);Classic c2 Classic(Piano Sonata in B flat, Fantasia in C, Alfred Brendel, Philips, 2, 57.17);Cd *pcd c1;cout Using object directly:\n;c1.Report(); // use Cd methodc2.Report(); // use Classic methodcout Using type cd *pointer to objects:\n;pcd-Report(); // use Cd method for cd objectpcd c2;pcd-Report(); // use Classic method for classic objectcout Calling a function with a Cd reference argument:\n;Bravo(c1);Bravo(c2);cout Testing assignment: ;Classic copy;copy c2;copy.Report();system(pause);return 0; }void Bravo(const Cd disk) {disk.Report(); }运行结果 Microsoft Windows [版本 10.0.19044.2728] (c) Microsoft Corporation。保留所有权利。C:\Users\81228\Documents\Program\VScode C Program\chapter13\13.1g cd.cpp classic.cpp main.cpp -o main main.cpp: In function int main(): main.cpp:9:41: warning: ISO C forbids converting a string constant to char* [-Wwrite-strings]Cd c1(beatles, Capitol, 14, 35.5);^ main.cpp:9:41: warning: ISO C forbids converting a string constant to char* [-Wwrite-strings] main.cpp:10:104: warning: ISO C forbids converting a string constant to char* [-Wwrite-strings]Classic c2 Classic(Piano Sonata in B flat, Fantasia in C, Alfred Brendel, Philips, 2, 57.17);^ main.cpp:10:104: warning: ISO C forbids converting a string constant to char* [-Wwrite-strings] main.cpp:10:104: warning: ISO C forbids converting a string constant to char* [-Wwrite-strings]C:\Users\81228\Documents\Program\VScode C Program\chapter13\13.1main Using object directly: Information: Performers: beatles Label: Capitol Selections: 14 Playtime: 35.5 Information: Performers: Alfred Brendel Label: Philips Selections: 2 Playtime: 57.17 Major works: Piano Sonata in B flat, Fantasia in C Using type cd *pointer to objects: Information: Performers: beatles Label: Capitol Selections: 14 Playtime: 35.5 Information: Performers: Alfred Brendel Label: Philips Selections: 2 Playtime: 57.17 Major works: Piano Sonata in B flat, Fantasia in C Calling a function with a Cd reference argument: Information: Performers: beatles Label: Capitol Selections: 14 Playtime: 35.5 Information: Performers: Alfred Brendel Label: Philips Selections: 2 Playtime: 57.17 Major works: Piano Sonata in B flat, Fantasia in C Testing assignment: Information: Performers: Alfred Brendel Label: Philips Selections: 2 Playtime: 57.17 Major works: Piano Sonata in B flat, Fantasia in C 请按任意键继续. . .C:\Users\81228\Documents\Program\VScode C Program\chapter13\13.12. 使用动态内存分配重做练习1 完成练习1但让两个类使用动态内存分配而不是长度固定的数组来记录字符串。 代码 cd.h #ifndef CD_H_ #define CD_H_class Cd { // represents a CD disk private:char *performers;char *label;int selections; // number of selectionsdouble playtime; // playing time in minutepublic:Cd(char *s1, char *s2, int n, double x);Cd(const Cd d);Cd();virtual ~Cd();virtual void Report() const; // reports all CD datavirtual Cd operator(const Cd d); };#endifcd.cpp #include cd.h #include iostream #include cstring using std::strcpy; using std::strlen;Cd::Cd(char *s1, char *s2, int n, double x) {performers new char[strlen(s1) 1];strcpy(performers, s1);label new char[strlen(s2) 1];strcpy(label, s2);selections n;playtime x; } Cd::Cd(const Cd d) {performers new char[strlen(d.performers) 1];strcpy(performers, d.performers);label new char[strlen(d.label) 1];strcpy(label, d.label);selections d.selections;playtime d.playtime; } Cd::Cd() {performers new char[1];strcpy(performers, \0);label new char[1];strcpy(label, \0);selections 0;playtime 0.0; } Cd::~Cd() {delete[] performers;delete[] label; } void Cd::Report() const {using std::cout;using std::endl;cout Information:\n;cout Performers: performers endl;cout Label: label endl;cout Selections: selections endl;cout Playtime: playtime endl; } Cd Cd::operator(const Cd d) {if (this d)return *this;delete[] performers;delete[] label;performers new char[strlen(d.performers) 1];strcpy(performers, d.performers);label new char[strlen(d.label) 1];strcpy(label, d.label);selections d.selections;playtime d.playtime;return *this; }classic.h #ifndef CLASSIC_H_ #define CLASSIC_H_#include cd.hclass Classic : public Cd { private:char *majorWorks;public:Classic(char *m, char *s1, char *s2, int n, double x);Classic(char *m, const Cd cd);Classic();virtual ~Classic();virtual void Report() const;virtual Classic operator(const Classic c); };#endifclassic.cpp #include classic.h #include iostream #include cstring using std::strcpy; using std::strlen;Classic::Classic(char *m, char *s1, char *s2, int n, double x) : Cd(s1, s2, n, x) {majorWorks new char[strlen(m) 1];strcpy(majorWorks, m); } Classic::Classic(char *m, const Cd cd) : Cd(cd) {majorWorks new char[strlen(m) 1];strcpy(majorWorks, m); } Classic::Classic() : Cd() {majorWorks new char[1];strcpy(majorWorks, \0); } Classic::~Classic() {delete[] majorWorks; } void Classic::Report() const {using std::cout;using std::endl;Cd::Report();cout Major works: majorWorks endl; } Classic Classic::operator(const Classic c) {if (this c)return *this;Cd::operator(c);majorWorks new char[strlen(c.majorWorks) 1];strcpy(majorWorks, c.majorWorks);return *this; }main.cpp与练习1的main.cpp相同。 运行结果 C:\Users\81228\Documents\Program\VScode C Program\chapter13\13.2g cd.cpp classic.cpp main.cpp -o main main.cpp: In function int main(): main.cpp:9:41: warning: ISO C forbids converting a string constant to char* [-Wwrite-strings]Cd c1(beatles, Capitol, 14, 35.5);^ main.cpp:9:41: warning: ISO C forbids converting a string constant to char* [-Wwrite-strings] main.cpp:10:104: warning: ISO C forbids converting a string constant to char* [-Wwrite-strings]Classic c2 Classic(Piano Sonata in B flat, Fantasia in C, Alfred Brendel, Philips, 2, 57.17);^ main.cpp:10:104: warning: ISO C forbids converting a string constant to char* [-Wwrite-strings] main.cpp:10:104: warning: ISO C forbids converting a string constant to char* [-Wwrite-strings]C:\Users\81228\Documents\Program\VScode C Program\chapter13\13.2main Using object directly: Information: Performers: beatles Label: Capitol Selections: 14 Playtime: 35.5 Information: Performers: Alfred Brendel Label: Philips Selections: 2 Playtime: 57.17 Major works: Piano Sonata in B flat, Fantasia in C Using type cd *pointer to objects: Information: Performers: beatles Label: Capitol Selections: 14 Playtime: 35.5 Information: Performers: Alfred Brendel Label: Philips Selections: 2 Playtime: 57.17 Major works: Piano Sonata in B flat, Fantasia in C Calling a function with a Cd reference argument: Information: Performers: beatles Label: Capitol Selections: 14 Playtime: 35.5 Information: Performers: Alfred Brendel Label: Philips Selections: 2 Playtime: 57.17 Major works: Piano Sonata in B flat, Fantasia in C Testing assignment: Information: Performers: Alfred Brendel Label: Philips Selections: 2 Playtime: 57.17 Major works: Piano Sonata in B flat, Fantasia in C 请按任意键继续. . .C:\Users\81228\Documents\Program\VScode C Program\chapter13\13.23. baseDMA、lacksDMA、hasDMA类 修改baseDMA-lacksDMA-hasDMA类层次让三个类都从一个ABC派生而来然后使用与程序清单13.10相似的程序对结果进行测试。也就是说它应使用ABC指针数组并让用户决定要创建的对象类型。在类定义中添加virtual View()方法以处理数据显示。 代码 dma.h #ifndef DMA_H_ #define DMA_H_#include iostreamclass ABC { public:ABC(){};~ABC(){};virtual void View() 0; };class baseDMA : public ABC { private:char *label;int rating;public:baseDMA(const char *l null, int r 0);baseDMA(const baseDMA rs);virtual ~baseDMA();baseDMA operator(const baseDMA rs);friend std::ostream operator(std::ostream os, const baseDMA rs);virtual void View(); };class lacksDMA : public baseDMA { private:enum{COL_LEN 40};char color[COL_LEN];public:lacksDMA(const char *c blank, const char *l null, int r 0);lacksDMA(const char *c, const baseDMA rs);friend std::ostream operator(std::ostream os, const lacksDMA rs);virtual void View(); }; class hasDMA : public baseDMA { private:char *style;public:hasDMA(const char *s none, const char *l null, int r 0);hasDMA(const char *s, const baseDMA rs);hasDMA(const hasDMA hs);~hasDMA();hasDMA operator(const hasDMA hs);friend std::ostream operator(std::ostream os, const hasDMA hs);virtual void View(); };#endifdma.cpp #include dma.h #include iostream #include cstring using std::cout; using std::endl; using std::strcpy; using std::strlen; using std::strncpy;// baseDMA methods baseDMA::baseDMA(const char *l, int r) {label new char[strlen(l) 1];strcpy(label, l);rating r; } baseDMA::baseDMA(const baseDMA rs) {label new char[strlen(rs.label) 1];strcpy(label, rs.label);rating rs.rating; } baseDMA::~baseDMA() {delete[] label; } baseDMA baseDMA::operator(const baseDMA rs) {if (this rs)return *this;delete[] label;label new char[strlen(rs.label) 1];strcpy(label, rs.label);rating rs.rating;return *this; } std::ostream operator(std::ostream os, const baseDMA rs) {os Label: rs.label endl;os Rating: rs.rating endl;return os; } void baseDMA::View() {cout Label: label endl;cout Rating: rating endl; }// lacksDMA methods lacksDMA::lacksDMA(const char *c, const char *l, int r) : baseDMA(l, r) {strncpy(color, c, 39);color[39] \0; } lacksDMA::lacksDMA(const char *c, const baseDMA rs) : baseDMA(rs) {strncpy(color, c, COL_LEN - 1);color[COL_LEN - 1] \0; } std::ostream operator(std::ostream os, const lacksDMA ls) {os (const baseDMA )ls;os Color: ls.color endl;return os; } void lacksDMA::View() {baseDMA::View();cout Color: color endl; }// hasDMA methods hasDMA::hasDMA(const char *s, const char *l, int r) : baseDMA(l, r) {style new char[strlen(s) 1];strcpy(style, s); } hasDMA::hasDMA(const char *s, const baseDMA rs) : baseDMA(rs) {style new char[strlen(s) 1];strcpy(style, s); } hasDMA::hasDMA(const hasDMA hs) : baseDMA(hs) {style new char[strlen(hs.style) 1];strcpy(style, hs.style); } hasDMA::~hasDMA() {delete[] style; } hasDMA hasDMA::operator(const hasDMA hs) {if (this hs)return *this;baseDMA::operator(hs);delete[] style;style new char[strlen(hs.style) 1];strcpy(style, hs.style);return *this; } std::ostream operator(std::ostream os, const hasDMA hs) {os (const baseDMA )hs;os Style: hs.style endl;return os; } void hasDMA::View() {baseDMA::View();cout Style: style endl; }main.cpp #include dma.h #include iostream #include string using namespace std;int main() {int n;cout How many DMAs do you have? ;cin n;ABC *p_dma[n];char *t_label new char[50];int t_rating;int kind;for (int i 0; i n; i){cout Enter label: ;cin.getline(t_label, 50);cout Enter rating: ;cin t_rating;cout Enter 1 for baseDMA or 2 for lacksDMA or 3 for hasDMA: ;while (cin kind kind ! 1 kind ! 2 kind ! 3)cout Enter either 1 or 2 or 3: ;cin.ignore();switch (kind){case 1:p_dma[i] new baseDMA(t_label, t_rating);break;case 2:char t_color[40];cout Enter color: ;cin.getline(t_color, 40);p_dma[i] new lacksDMA(t_color, t_label, t_rating);break;case 3:char *t_style new char[20];cout Enter style: ;cin.getline(t_style, 20);p_dma[i] new hasDMA(t_style, t_label, t_rating);break;}while (cin.get() ! \n)continue;}cout endl;for (int i 0; i n; i){p_dma[i]-View();cout endl;}for (int i 0; i n; i){delete p_dma[i];}cout Done.\n endl;system(pause);return 0; }运行结果 Microsoft Windows [版本 10.0.19044.2728] (c) Microsoft Corporation。保留所有权利。C:\Users\81228\Documents\Program\VScode C Program\chapter13\13.3g dma.cpp main.cpp -o mainC:\Users\81228\Documents\Program\VScode C Program\chapter13\13.3main Enter label: Portabelly Enter rating: 8 Enter 1 for baseDMA or 2 for lacksDMA or 3 for hasDMA: 1Enter label: Blimpo Enter rating: 4 Enter 1 for baseDMA or 2 for lacksDMA or 3 for hasDMA: 2 Enter color: redEnter label: Buffalo Keys Enter rating: 5 Enter 1 for baseDMA or 2 for lacksDMA or 3 for hasDMA: 3 Enter style: MercatorEnter label: lable1 Enter rating: 10 Enter 1 for baseDMA or 2 for lacksDMA or 3 for hasDMA: 1Enter label: lable2 Enter rating: 3 Enter 1 for baseDMA or 2 for lacksDMA or 3 for hasDMA: 1Enter label: lable3 Enter rating: 1 Enter 1 for baseDMA or 2 for lacksDMA or 3 for hasDMA: 9 Enter either 1 or 2 or 3: 1Label: Portabelly Rating: 8Label: Blimpo Rating: 4 Color: redLabel: Buffalo Keys Rating: 5 Style: MercatorLabel: lable1 Rating: 10Label: lable2 Rating: 3Label: lable3 Rating: 1Done.请按任意键继续. . .C:\Users\81228\Documents\Program\VScode C Program\chapter13\13.34. Port类和VintagePort类 Benevolent Order of Programmers用来维护瓶装葡萄酒箱。为描述它BOP Portmaster设置了一个Port类并声明如下 #include iostream using namespace std; class Port { private:char *brand;char style[20]; // i.e., tawny, ruby, vintageint bottles;public:Port(const char *br none, const char *st none, int b 0);Port(const Port p); // copy constructorvirtual ~Port() { delete[] brand; }Port operator(const Port p);Port operator(int b); // add b to bottlesPort operator-(int b); // subtracts b from bottles , if availableint BottleCount() const { return bottles; }virtual void Show() const;friend ostream operator(ostream os, const Port p); };show()方法按下面的格式显示信息 Brand : Gallo Kind : tawny Bottles : 20operator()函数按下面的格式显示信息末尾没有换行符 Gallo, tawny, 20PortMaster完成了Port类的方法定义后派生了VintagePort类然后被解职——因为不小心将一瓶45度Cockburn泼到了正在准备烤肉调料的人身上VintagePort类如下显示 class VintagePort : public Port //style necessarily vintage { private:char* nickname; //i.e. , The Noble or Old Velvet, etc.int year; //vintage year public:VintagePort();VintagePort(const char* br, const char* st, int b, const char* nn, int y);VintagePort(const VintagePort vp);~VintagePort() { delete[] nickname; }VintagePort operator (const VintagePort vp);void show() const;friend ostream operator (ostream os, const VintagePort vp); };您被制定指定负责完成VintagePort。 a.第一个任务是重新创建Port方法定义因为前任被开除时销毁了方法定义。 b.第二个任务是解释为什么有的方法重新定义了而有些没有重新定义。 c.第三个任务解释为何没有将operator () 和operator ()声明为虚的。 d.第四个任务是提供VintagePort中各个方法的定义。 答 a.第一个任务是重新创建Port方法定义因为前任被开除时销毁了方法定义。 #include port.h #include iostream #include cstring using namespace std;Port::Port(const char *br, const char *st, int b) {brand new char[strlen(br) 1];strcpy(brand, br);strcpy(style, st);bottles b; } Port::Port(const Port p) // copy constructor {brand new char[strlen(p.brand) 1];strcpy(brand, p.brand);strcpy(style, p.style);bottles p.bottles; } Port Port::operator(const Port p) {if (this p)return *this;delete[] brand;brand new char[strlen(p.brand) 1];strcpy(brand, p.brand);strcpy(style, p.style);bottles p.bottles;return *this; } Port Port::operator(int b) // add b to bottles {bottles b;return *this; } Port Port::operator-(int b) // subtracts b from bottles , if available {bottles - b;return *this; } void Port::Show() const {cout Brand: brand endl;cout Kind: style endl;cout Bottles: bottles endl; } ostream operator(ostream os, const Port p) {os p.brand , p.style , p.bottles;return os; }b.第二个任务是解释为什么有的方法重新定义了而有些没有重新定义。 当派生类成员函数需要处理派生类独有的成员变量时需要重新定义方法如果不需要处理派生类独有的成员变量直接调用基类的方法即可。 c.第三个任务解释为何没有将operator () 和operator ()声明为虚的。 a).如果要在派生类中重新定义基类的方法则将它设置为虚方法。但是基类的operator () 和派生类的operator () 形参不一样根本不是一个类方法不存在重新定义的问题因从也不必声明为虚的。 b).operator()函数是友元函数友元函数不能是虚函数因为友元不是类成员而只有类成员才能是虚函数。 d.第四个任务是提供VintagePort中各个方法的定义。 #include VintagePort.h #include iostream #include cstring using namespace std;VintagePort::VintagePort() : Port() { } VintagePort::VintagePort(const char *br, const char *st, int b, const char *nn, int y) : Port(br, st, b) {nickname new char[strlen(nn) 1];strcpy(nickname, nn);int year y; } VintagePort::VintagePort(const VintagePort vp) : Port(vp) {nickname new char[strlen(vp.nickname) 1];strcpy(nickname, vp.nickname);int year vp.year; } VintagePort VintagePort::operator(const VintagePort vp) {if (this vp)return *this;Port::operator(vp);delete[] nickname;nickname new char[strlen(vp.nickname) 1];strcpy(nickname, vp.nickname);strcpy(nickname, vp.nickname);year vp.year;return *this; } void VintagePort::show() const {Port::Show();cout Nick Name: nickname endl;cout Year: year endl; } ostream operator(ostream os, const VintagePort vp) {os (const Port )vp;os vp.nickname , vp.year;return os; }
http://www.dnsts.com.cn/news/43843.html

相关文章:

  • 肇庆网站建设方案外包拼多多网络营销方式
  • 聊城做网站的地方网站后台和前台
  • 免费网站备案网站域名销售
  • 广安门内网站建设公司在选择网站时应考虑什么
  • 个人网站心得百度搜不到WordPress文章
  • wordpress图片整站商务网站规划与设计实训报告
  • wordpress站点是什么1688货源网下载app
  • 网站主页设计注意点中国菲律宾地图全图
  • wordpress在线更新要多久搭建网站seo
  • 对企业网站建设的建议怎么用ftp备份网站
  • 哪些网站做视频能赚钱营销型企业网站的含义
  • 做外贸无网站如何做俄罗斯最新
  • 黄江网站设计注册企业邮箱免费
  • 建设网站青岛市广告设计公司招聘
  • 域名 备案 没有网站注册监理工程师注册查询系统
  • 平凉市网站建设网站作业
  • 网站建设企业类型是什么科协网站建设建议
  • 网站建设沧州中国企业网信息查询
  • 网站宣传方案广东东莞直播基地
  • 做系统用哪个网站好安康升降平台
  • 电销做网站项目鸿蒙系统软件开发教程
  • 网站开发需要什么专业知识nodejs网站开发教程
  • 如何向百度提交网站海会主机
  • 衡阳城乡建设局网站wordpress弹框登陆
  • 屏蔽网站接口js广告wordpress文字模板下载
  • 网站建设嘉兴公司电话公司网上注册
  • 电子商务网站开发计划书招c1驾驶员300元一天
  • 网站建设与维护教学计划公司图标设计大全免费 logo
  • 深圳网站建设如何制作域名iis网站添加
  • 石大远程网页设计及网站建设答案二级域名的网站备案