最简单的结构体定义、输出

 专业     |      2020-03-18 15:47

#include<stdio.h>
#include<conio.h>
#include<stdlib.h>
#include<windows.h>
#include<time.h>    
#define MAX  3200
#define LEN  sizeof(Snake)
typedef unsigned char uchar;
//------------------------
typedef struct snake{                  
   char x;
   char y;
   struct snake *next;
   struct snake *last;
}Snake;//双向链表
Snake *h,*tp1,*tp2;
Snake *t,*hp1,*hp2;//表尾tail
//----------------------(数组图片)结构体化---------------------------------
 typedef struct Pic{
  char x[MAX];
  char y[MAX];
  int pnum;
}PIC;
 //-----------------------------------------------------------------------
PIC p0;
//------------------------
char f;//食物标志
int  m=0,n=0;//食物位置
int a=20;
//------------------------
unsigned short  color=5;//设置蛇头颜色
int  score=0;
int _score=0;//历史分数变量
step=0;//记录吃食物所用步数
foodlose=0;//记录未吃到的食物数
//-------颜色设置-----------------
void colorf(unsigned short  t)
{
    HANDLE  color;//创建句柄    color是变量名可以自己定义
    color=GetStdHandle(STD_OUTPUT_HANDLE);//句柄实例化
    SetConsoleTextAttribute(color,t);//设置字体颜色
}

// 坦克大战.cpp : Defines the entry point for the console application.
//思路简介:坦克大战采用的是面向对象的编程思想,其中离不开对类及线程的理解和使用
#include "stdafx.h"
#include<windows.h>
#include <process.h>
#include"pic_.h"

最简单的结构体定义、输出

//---------------------------
void point(int x,int y)//起始点(0,0)
{
 int i,dx=0,dy=0;
 static int x0=0,y0=0,j=1;//x0,y0表示当前行和当前列
 if(x==-1&&y==-1)  {x0=y0=0;j=1;}//用point(-1,-1)刷函数-相对于(0,0)点开始打点,未刷屏则相对于
 //当前点,一般用于重新绘图时
 if(x==0&&y==0&&j==1) { j=0;
 if(x==h->x&&y==h->y)  printf("○");
 else if(x==24||x==0||y==0||y==20)     {colorf(0x0f); printf("□"); colorf(9);}
    else printf("●");return;}
 if(x==0&&y==0&&j==0)  return;//打两次(0,0)时略去第二个
 dx=x-x0;
 if(!dx) dy=y-y0;  //dx=0,同一行
 else   dy=y;
 if(dy<0||dx<0)  return;
 if(x==0&&y!=0&&dy==y&&j)    printf("  ");
 if(dy==0&&y!=0)   return;
 for(i=0;i<dx;i++)     putchar('n');
    if(dx&&y!=0)       printf("  ");
    for(i=1;i<dy;i++)      printf("  ");
    //putchar(4);
 //--------判断蛇头---------
 if(x==h->x&&y==h->y)     {colorf(color);printf("■");colorf(9);}
 else if(x==24||x==0||y==0||y==20)   {colorf(0x0f); printf("□"); colorf(9);}
 else printf("●");
 //---------------
 x0=x;
 y0=y;
}//注:每次打的点必须在前一个点后面,且第一次调用时必须先清屏
// ⊙★○▲△▽○◇☆♀♂㊣╲■▕╱╲▏▏卐卍♀◢◥◤
//--------整理pic-------
void  sort(char*tx,char*ty)
{
    int i,j,t,k;
 int m,n,l;
 //----第一步排tx(并保持tx与ty之间的对应关系)---
 for(i=1;i<p0.pnum;i++)
 {
  t=tx[i];
  k=ty[i];
  for(j=i-1;j>=0;j--)
   if(t<tx[j]) {  tx[j+1]=tx[j]; ty[j+1]=ty[j]; }
   else break;
  tx[j+1]=t;
  ty[j+1]=k;
 }
   //--------第二步逐行排ty----------
 
    for(i=tx[0],j=0;i<=tx[p0.pnum-1];i++)//从第tx[0]到tx[p0.pnum-1]行 
 { 

#define uchar unsigned char //坐标类型   屏幕上所有的坐标均为非负
#define uint    unsigned int
//----全局变量
#define TK  20//最大坦克数量 
HANDLE hThread[TK];//多线程句柄
//------------
uint Base_coefficient=0;//当前基址系数
uchar vanish=0;//坦克消失消息,用来改变基址
//----pic请求变量,当每一个类装好pic之后,则改变对应变量值,发出请求,等到请求满后便调用picture(),显示一帧图片
uchar tk_pic[TK]={0};
uchar bt_pic[TK]={0};
//------------
class BULLET;
class TANK//坦克总类              
{
  public:
    uint BASE; //内部基址
    uint base_coefficient; //外部基址系数
    uchar x,y;//坦克中心位置
       uchar a,b;//a是炮筒的九宫格代码,b是空格的九宫格代码 
    uchar tankcode[8];//借助坦克代码(九宫格旋转公式),控制坦克形状(转向)
    TANK(uchar tx,uchar ty)
    {
    x=tx;y=ty;
       a=2;b=8;
    base_coefficient=Base_coefficient++;//将全局量转化为类体私有量,再将该系数加一抛出
    BASE=9*base_coefficient;
    shape(); 
    }//构造函数 给出坦克中心点,绘出坦克图形
       friend  BULLET;//将子弹类声明为坦克类的友元类,这样的话友元类BULLET中的所有函数都是TANK的友元函数,可以访问TANK的所有公共成员
    void shape(void)//  shape-塑形   
    {
      uchar i,j;
   tankcode[0]=a;
   for(i=1,j=1;i<10;i++)//i=1,2,...,9
   {
    if(i==a||i==b) continue;
    tankcode[j++]=i;
   }
    }
    void tank_vanish(void)
    {
   uint i=base_coefficient;
   //for()//修改其后tank的基址
   //{
   
竞博下载 ,  // }
   Base_coefficient--;
   //vanish=1;//发送消影消息
    }
    void tank_dis(uchar f)
    {  
     uint i;
     //---------------------
     //if(vanish&&BASE>=9) {BASE-=9;vanish=0;}
     //if(vanish&&BASE==0) {vanish=0;}
     p0.pnum=BASE;
        switch(tankcode[0])//炮筒
     {
        case 2: p0.x[BASE]=x-1;p0.y[BASE]=y;p0.z[BASE]=2;break;
        case 4: p0.x[BASE]=x;p0.y[BASE]=y-1;p0.z[BASE]=3;break;
        case 6: p0.x[BASE]=x;p0.y[BASE]=y+1;p0.z[BASE]=3;break;
     case 8: p0.x[BASE]=x+1;p0.y[BASE]=y;p0.z[BASE]=2;break;
     }
     p0.pnum++;
     for(i=1;i<8;i++)
     {
      switch(tankcode[i])
      {
         case 1:   p0.x[BASE+i]=x-1;p0.y[BASE+i]=y-1;break;
      case 2:   p0.x[BASE+i]=x-1;p0.y[BASE+i]=y;break;
      case 3: p0.x[BASE+i]=x-1;p0.y[BASE+i]=y+1;break; 
      case 4:   p0.x[BASE+i]=x;p0.y[BASE+i]=y-1;break;
      case 5: p0.x[BASE+i]=x;p0.y[BASE+i]=y;break;
      case 6: p0.x[BASE+i]=x;p0.y[BASE+i]=y+1;break;
      case 7: p0.x[BASE+i]=x+1;p0.y[BASE+i]=y-1;break;
      case 8: p0.x[BASE+i]=x+1;p0.y[BASE+i]=y;break;
      case 9: p0.x[BASE+i]=x+1;p0.y[BASE+i]=y+1;break;
      }
      p0.z[BASE+i]=1;//设置显示的样式
      p0.pnum++;
     }
          //---------------------
     if(f) 
     {
       tk_pic[base_coefficient]=1;//发出请求---设置一个专门的线程来满足这些请求
       while(tk_pic[base_coefficient]); 
     }
    }
    void tank_rotate(uchar direction)
    {
    a=direction;//2864  上 下左 右
       b=10-a;
    shape();
       return;
    }
    void tank_con(char c)
    {
     if(c==0x50)//向下
     {
    if(x>=30)  x=30;
       else  x++;
    if(a!=8) tank_rotate(8);
    tank_dis(1);  
     }                      
    else if(c==0x4b)//向左
    {  
       if(y<=1)  y=1;
    else y--;
    if(a!=4) tank_rotate(4);
    tank_dis(1);
    }
          else if(c==0x4d)//向右
    {
     if(y>=72) y=72;
       else  y++;
       if(a!=6) tank_rotate(6);
    tank_dis(1);
    }
    else if(c==0x48)//向上
    {
     if(x<=1) x=1;
    else x--;
    if(a!=2)  tank_rotate(2);
    tank_dis(1);
    }
    c='';
 }
};
class TANK_derive_1:public TANK//第二控制坦克
{
   public: 
    TANK_derive_1(uchar tx,uchar ty):TANK(tx,ty) {  }
       void tank_con(char c) //重载基类中的该函数
    {
     if(c=='s'||c=='S')//向下
     {
    if(x>=30)  x=30;
       else  x++;
    if(a!=8) tank_rotate(8);
    tank_dis(1);  
     }                      
    else if(c=='a'||c=='A')//向左
    {  
       if(y<=1)  y=1;
    else y--;
    if(a!=4) tank_rotate(4);
    tank_dis(1);
    }
          else if(c=='d'||c=='D')//向右
    {
     if(y>=72) y=72;
       else  y++;
       if(a!=6) tank_rotate(6);
    tank_dis(1);
    }
    else if(c=='w'||c=='W')//向上
    {
     if(x<=1) x=1;
    else x--;
    if(a!=2)  tank_rotate(2);
    tank_dis(1);
    }
    c='';
 }
};
class TANK_derive_2:public TANK//敌人坦克
{
   public:
    TANK_derive_2(uchar tx,uchar ty):TANK(tx,ty) { }
     void enemy_autogo(void)
  {
   if(y>=72) y=5;
   TANK::tank_con(0x4d);Sleep(20);
  }
};
uchar Thread_Exit[TK]={0};//线程退出数组
class BULLET//子弹类
{
   public:
    uchar X,Y;//子弹坐标   
    void bullet_destroy(uchar x,uchar y,TANK &tank_t)//子弹线程关闭其他线程
    {
         int i;int t=0;
   for(i=0;i<p0.pnum;i++)
    if(p0.x[i]==x&&p0.y[i]==y)   {t++; if(t==2)  {tank_t.tank_vanish();Thread_Exit[0]=1;t=0;return;} }
    }
    void bullet_dis(TANK &tank_t)
    {
     uint i,j;
     j=tank_t.BASE;tank_t.BASE++;
           if(tank_t.a==2)//前射子弹
     { 
      X=tank_t.x-2;Y=tank_t.y;//初始位置
      for(i=X;i>0;i--)
      {
       p0.x[j]=i;p0.y[j]=Y; p0.z[j]=4;//子弹属性
       Sleep(10);
       tank_t.tank_dis(1);
       bullet_destroy(i,Y,tank_t);
      }
     }
     if(tank_t.a==8)//后射子弹
     {
      X=tank_t.x+2;Y=tank_t.y;
      for(i=X;i<30;i++)
      {
       p0.x[j]=i;p0.y[j]=Y;p0.z[j]=4;//子弹属性
       Sleep(10);
       tank_t.tank_dis(1);
       bullet_destroy(i,Y,tank_t);
      }
     }
     if(tank_t.a==4)//左射子弹
     {
    X=tank_t.x;Y=tank_t.y-2;
    for(i=Y;i>0;i--)
    {
       p0.x[j]=X;p0.y[j]=i; p0.z[j]=4;//子弹属性
                   Sleep(10);
       tank_t.tank_dis(1);
       bullet_destroy(X,i,tank_t);
    }
     }
     if(tank_t.a==6)//右射子弹
     {
    X=tank_t.x;Y=tank_t.y+2;
    for(i=Y;i<72;i++)
    {
       p0.x[j]=X;p0.y[j]=i; p0.z[j]=4;//子弹属性
       Sleep(10);
       tank_t.tank_dis(1);
       bullet_destroy(X,i,tank_t);
    }
     }
     tank_t.BASE--;
     tank_t.tank_dis(1);
    }
};
//-----------全局变量------------
TANK tank0(8,8);
//TANK_derive_1 tank1(20,20);
TANK_derive_2 tank_0(4,20);
uchar tkbt[TK]={0};//用于坦克线程和子弹线程间通信
uchar tkbt_[TK]={0};
//---------------线程入口函数
UINT WINAPI  pic_ex(LPVOID lpParam)
{//显示输出控制
 while(1)
 {
  if((Thread_Exit[0]||tk_pic[1])&&(tk_pic[0]))
  {   //坦克大炮位置数组首地址,BASE基址数组首地址
     tank0.tank_dis(0);//不产生申请只装值,此时是被动式显示,如发送请求则是主动式显示
     if(!Thread_Exit[0])  tank_0.tank_dis(0);
     picture();
     tk_pic[0]=0;tk_pic[1]=0;
  }
 }
 return 0;
}
UINT WINAPI bullet_con(LPVOID lpParam)
{
  BULLET bullet0,bullet1;
  while(1)
  {
   if(tkbt[0])  {  tkbt[0]=0;bullet0.bullet_dis(tank0); }
   //if(tkbt[1])  {  tkbt[1]=0;bullet1.bullet_dis(tank1);}
  }
  return 0;
}
UINT WINAPI tank_enemy(LPVOID lpParam)

 while(!Thread_Exit[0])
 {
     tank_0.enemy_autogo(); 
 }
    return 0; 
}
UINT WINAPI  tank_soldier(LPVOID lpParam)
{  
 tkbt[0]=tkbt[1]=0;
    tank0.tank_dis(1);
    //tank1.tank_dis(1);
    while(!Thread_Exit[1])
 {
     tank0.tank_dis(1);
 }
 return 0;
}
UINT WINAPI global_con(LPVOID lpParam)
{
 Thread_Exit[1]=1;
 while(1)
 {
    uchar c;
    if(kbhit())
    {
        c=getch();
     if(c==0X0D)  {   tkbt[0]=1;  }
     //if(c=='q'||c=='Q') {tkbt[1]=1;}
     tank0.tank_con(c);
     //tank1.tank_con(c);
     c='';
    }
    /*if(Thread_Exit[0])  
    {
     Sleep(30);Thread_Exit[0]=0;
     hThread[3]=(HANDLE)::_beginthreadex(NULL,NULL,tank_enemy,NULL,0,NULL);
    
    }     */
    tank0.tank_dis(1);
 }
 return 0;
}
int main(int argc, char* argv[])
{
    //---------------
 hThread[0]=(HANDLE)::_beginthreadex(NULL,NULL,pic_ex,NULL,0,NULL);//立即执行的线程
 hThread[1]=(HANDLE)::_beginthreadex(NULL,NULL,global_con,NULL,0,NULL);
 hThread[2]=(HANDLE)::_beginthreadex(NULL,NULL,bullet_con,NULL,0,NULL);
    hThread[3]=(HANDLE)::_beginthreadex(NULL,NULL,tank_enemy,NULL,0,NULL);
    hThread[4]=(HANDLE)::_beginthreadex(NULL,NULL,tank_soldier,NULL,0,NULL);
    //-----------------------
 ::WaitForMultipleObjects(5,hThread,TRUE,INFINITE);
 ::CloseHandle(hThread[0]);
 ::CloseHandle(hThread[1]);
 ::CloseHandle(hThread[2]);
 ::CloseHandle(hThread[3]);
 ::CloseHandle(hThread[4]);
    //---------------------
 return 0;
}

#include<stdio.h>

   
       l=0;  //j的最大值不能超过p0.pnum
       while(tx[j]==i)
        //此处只依靠tx[*]的值去做判断,容易出现超出数组寻址范围的情况,因为如果对于未定义的内存

//下面是另外一个包含文件,我个人感觉他的功能很像console下的一个“显卡”,是我自己呕心沥血写成的,

struct Date

        //空间(此处是明确的,tx后的地址就是ty的地址),其值虽然相对
        //不变,但总体(理论上)应该是不确定的(这可能取决于各自的机器),因此尽管超出规定的

//我写的控制台游戏都使用了这个头文件,当然除了自娱自乐没什么实际的意义。

{

        //范围,仍然有可能
        //满足这个判别式,从而造成寻址越界的情况
        {  
            if(j==p0.pnum)   break;//后来加的限制条件,没有它会出现一系列的奇葩现象
            j++;l++;
         }//得到tx[*]行的点数l
         //当tx[*]全赋0且ty[0]=0,此处寻址越界,由于tx[*]寻址越界后,寻到了ty[*]处,他们地址是连续的,
         //而此时的ty[0]正好满足ty[0]=tx[0]=0,这就造成了寻址越界,因此加上一条限制语句(如上),
         //也证明上面的猜想是正确的
         if(l==1||l==0)  continue;
        //*************************************
    for(m=j-l;m<j-1;m++)
    { k=m;      
      for(n=m+1;n<j;n++)
      if(ty[n]<ty[k] )  k=n;
      if(k!=m)
     {
     t=ty[k];
     ty[k]=ty[m];
     ty[m]=t;}  }
 }
}
//-------光标定位-------------------------
void  gotoxy(int x,int y)
{
 COORD c;
 c.X=x;c.Y=y;
 SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),c);
}
 //--------------------------------------
void picture()
{
   int i;
   sort(p0.x,p0.y);
    //------刷新--------
   point(-1,-1);
   system("cls");
//--------------------------------
  for(i=0;i<p0.pnum;i++)
  //{gotoxy(p0.y[i]*2,p0.x[i]);printf("□"); } //测试gotoxy()
  point(p0.x[i],p0.y[i]);
  putchar(10);
}
//------------------------------
void s_play(Snake *h);
void s_add_t(char a,char b)//加尾
{
 //---开辟新节点并链接---
    tp2=(Snake*)malloc(LEN);
 tp2->x=a;
 tp2->y=b;
    tp1->next=tp2;
    tp2->last=tp1;
 tp2->next=NULL;
 //-------------------
 t=tp1=tp2;
}
void s_add_h(char a,char b)//加头
{
  hp2=(Snake*)malloc(LEN);
  hp2->x=a;
  hp2->y=b;
  hp2->last=NULL;
  hp2->next=hp1;
  hp1->last=hp2;
  h=hp1=hp2;
}
void  s_sub(char a)     
{  
   Snake* p;
    if(a>0){
     p=h;
  hp1=h=h->next;//此处要当心hp1应始终和h保持同步,在创建一个新h时默认hp1指向当前h,此处若不更新
  //hp1将为NULL,导致链接错误
  h->last=NULL;} //删去蛇头
 if(a<0){
  p=t;
  tp1=t=t->last;
  t->next=NULL;
 }//删去蛇尾
    free(p);
}   
void s_play(Snake *p)

 int i=89;//前面点做图框
 //--------------(墙壁)------------------------
 int j=0;
 for(j=0;j<20;j++)
 { p0.x[j]=24; p0.y[j]=j;             }
 for(j=0;j<20;j++)
 { p0.x[j+20]=0;p0.y[j+20]=j;   }
 for(j=0;j<25;j++)
 { p0.x[j+40]=j;p0.y[j+40]=0;   }
  for(j=0;j<25;j++)
 { p0.x[j+65]=j;p0.y[j+65]=20; }
//---------------------------------------------
 if(f)   { p0.x[i]=m=rand()%23+1; p0.y[i]=n=rand()%19+1;  f=0;}//放置食物
 else  {   p0.x[i]=m;  p0.y[i]=n; }
 //----------- -----------------
 i++;
 p0.x[i]=p->x;
 p0.y[i]=p->y;
// printf("%dt%dn",p->x,p->y);
 i++; 
   do    
 {
  if(p->next==NULL)   break;
  p=p->next;
     p0.x[i]=p->x;
  p0.y[i]=p->y;
 // printf("%dt%dn",p->x,p->y);
  i++; 
 } while(p->next!=NULL);
     p0.pnum=i;
  //getch();
  colorf(9);
  picture();
  colorf(10);
  printf("n当前得分:%dn当前蛇头(%d,%d)t当前食物(%d,%d)n当前步数:%d(step<=50)t未吃到食物数:%dn",score,h->x,h->y,m,n,step,foodlose);
  printf("按z可自动行走步数:%dt按q退出t按e暂停n",a);
  gotoxy(48,8);
  printf("%st%s",__DATE__,__TIME__);
  gotoxy(2,23); //可以在不破坏原图的情况下定位光标
//system("cls");point(-1,-1);point(23,2);
  printf("版权制作 吴侯所有  213.6.23");
}
void init()
{
   system("color 07");
//------食物设置---------
   srand(time(NULL));
   f=1;
  m=n=0;
  //---------使用说明--------
  printf("nnnnnnntt按键盘w、s、a、d键控制蛇的上下左右移动n");
  printf("tt按z键可自动行走n");
  printf("tt按键盘q键选择退出 按e键暂停n"); 
  printf("tt注意:当蛇头触碰到墙壁时会:game over!ntt");
  printf("输入你希望的蛇头颜色(0-15):ntt");
  scanf("%d",&color);
  system("pause");
  //getch();
system("color 09");
 //-----------------------
    t=h=hp1=tp1=(Snake*)malloc(LEN);
    tp1->last=NULL;
    tp1->next=NULL;//空链表
 tp1->x=8;
 tp1->y=4; //蛇头
 //-----初始化----------
    s_add_t(8,5);
    s_add_t(8,6);
    s_add_t(8,7);
    s_play(h);
   //----------------
}
void main()
{
 char c;
 char c_='d';
 char c__='a';
 //--------函数声明-------
 void save();
 void load();
 void creat();
 void gameover();
 void move(char c);
 char autogo();
 //------------------------
 creat();//外部文件生成判断
 init();
 while(1)
 {
        if(kbhit()) { c_=c=getch();  move(c); }
  else {
   if(c_=='e'||c_=='z'||c_=='E'||c=='Z') c_=c__;
   move(c_);
   c__=c_;
   _sleep(200);}
 }
 
}
//-----方向控制-------------------------
void move(char c)
{
 if(h->x<=0||h->x>=24||h->y<=0||h->y>=20)   gameover(); //撞墙判断
 switch(c)
 {
   case 'W':
   case 'w':{
       {s_sub(-1);s_add_h(h->x-1,h->y);step++; }
         break;  }
   case 'S':
   case 's':{ 
       {s_sub(-1);s_add_h(h->x+1,h->y);step++;}
         break;}
    case 'A':
    case 'a':{
     {s_sub(-1);s_add_h(h->x,h->y-1);step++;}
        break;  }
 case'D':
    case 'd':{
     { s_sub(-1);s_add_h(h->x,h->y+1);step++; } 
          break; }
 case'Q':
    case 'q' : {  system("cls");
     system("color 0a"); printf("nnnnnnnnnnnnnttt退出?('y' or 'n')ntttt");
        if(getchar()=='y'||getchar()=='Y')    {printf("ttt"); exit(0); }
        else   system("color 09"); }
 }
    //putchar(c_);
 //getch();
 if(h->x<=0||h->x>=24||h->y<=0||h->y>=20)   gameover(); //撞墙判断
 if(c=='z'||c=='Z')   while(a) { move(autogo());a--; }
 if(c=='e'||c=='E')   system("pause"); //暂停
    if((h->x==m&&h->y==n)||(t->x==m&&t->y==n)) 
 { s_add_t(t->x,t->y+1); step=0;score++;f=1;printf("a");
   if(a<20) a=20;else a++;                                         }  //吃到食物,增加节点,并重新放置食物
    if(step==50) { step=0;f=1;foodlose++;printf("a");    }//走完u步未吃到食物则更新食物
    s_play(h);
}
//------------自动寻找食物演示----------------
char   autogo()
{
 char c=0;
      if(h->x>m)  c='w';
     if(h->x<m)  c='s';
  if(h->x==m){
        if(h->y>n) c='a';
        if(h->y<n) c='d'; }
 return c;

 

    int month;

}
//------------------------------------------
void gameover()

    load();
       system("cls");
    system("color 0a");
    printf("nnnnnnnnntttgame over!ntt");
    printf("t您的得分是:%dnttt",score);
    printf("历史最高分数:%dnttt",_score);
    save();
    getch(); 
    Sleep(1000);exit(0);
}
//-----------------数据保存-----------------------
 void save()
 {
  FILE *fp;
  fp=fopen("mtcs.mine","w");
  if(fp==NULL) printf("nttt数据保存失败!n");
     if(score<_score) {fclose(fp); return;} 
  fprintf(fp,"%d",score);
  fclose(fp);
 }
//------------------数据提取------------------
 void load()
 {
  FILE *fp;
  fp=fopen("mtcs.mine","r");
  if(fp==NULL)  printf("nttt加载数据失败!n");
  fscanf(fp,"%d",&_score);
  fclose(fp);
 }
 //------------------------------------------
 void  creat() //判断文件是否存在,若无则新建
 {
  void save();
  FILE *fp;
     fp=fopen("mtcs.mine","r");
  if(fp==NULL)   save();
  else fclose(fp);
}
//-------------------------------------------------

//pic.h是从picture.h提取出使用的部分代码组成的头文件,主要因为picture.h太乱,不方便在别的程序里引用
#include<stdio.h>
#include<conio.h>
#include<stdlib.h>
#include<windows.h>
#define MAX  3200
typedef unsigned char uchar;
//----------------------结构体化------------------------------------------
typedef struct Pic{
  uchar x[MAX];
  uchar y[MAX]; //x,y为坐标
  uchar z[MAX];// pixel形状及颜色信息
  int pnum;
}PIC;//pixel的坐标为非负,但排序的序号i,j应设为int,插入排序时,负数为退出循环的界限
 //-----------------------------------------------------------------------
PIC p0={
{0},
{0},
{0},
0}; //未赋值的内存自动赋0
 PIC pt={
{0},
{0},
{0},
0}; //采用本地备份数据显示方式,不破坏原数据

    int day;
    int year;
}birthday;
struct Student

//-----------------
void point_ex(int x,int y,char*p)//起始点(0,0)
{
 int i,dx=0,dy=0;
 static int x0=0,y0=0,j=1;//x0,y0表示当前行和当前列
 if(x==-1&&y==-1)  {x0=y0=0;j=1;}//用point(-1,-1)刷函数-相对于(0,0)点开始打点,未刷屏则相对于
 //当前点,一般用于重新绘图时
 if(x==0&&y==0&&j==1) { j=0; printf("%s",p);return;}
 if(x==0&&y==0&&j==0)  return;//打两次(0,0)时略去第二个
 dx=x-x0;
 if(!dx) dy=y-y0;  //dx=0,同一行
 else   dy=y;
 if(dy<0||dx<0)  return;
 if(x==0&&y!=0&&dy==y&&j)    printf("  ");//这个if语句的意思是:锁定第零行,除去第零列
 //所打的第一个点且保证未打(0,0)时,执行后面的语句
 if(dy==0&&y!=0)   return;//滤去空行以及相同的点
 for(i=0;i<dx;i++)     putchar('n'); //i=0第一行为空白行
    if(dx&&y!=0)       printf("  ");//换行时如果这一行的第零列没打的话,则自动加一列
    for(i=1;i<dy;i++)      printf("  ");//打完一个点后光标已移到下一个点,因此dy=1时,这条语句应该不执行
    //putchar(4);
 //--------判断蛇头---------
     printf("%s",p);
 //---------------
 x0=x;
 y0=y;
}//注:每次打的点必须在前一个点后面,且第一次调用时必须先清屏
// ⊙★○▲△▽○◇□■☆♀♂㊣╲▕╱╲▏▏卐卍♀◢◥◤
//------------------------------------------ 
//-----------------
void pic_copy(uchar*,uchar* ,uchar *,int);
void pic_sort(uchar*,uchar*,uchar*,int);
void pic_debug()
{
 int i;
    //-----debug view----------
    printf("n---------debug---------------n");
 for(i=0;i<p0.pnum;i++)
 printf(i%18==17?"%dn":"%dt",p0.x[i]);
 printf("n----------------------------n");
    for(i=0;i<p0.pnum;i++)
 printf(i%18==17?"%dn":"%dt",p0.y[i]);
    putchar(10); 
}
void picture(void)
{
   int i;
   pic_copy(p0.x,p0.y,p0.z,p0.pnum);
   pic_sort(pt.x,pt.y,pt.z,pt.pnum);
   //------刷新--------
      point_ex(-1,-1,NULL);
      system("cls");
   for(i=0;i<pt.pnum;i++)
      {
    switch(pt.z[i])
    {
        case 1: point_ex(pt.x[i],pt.y[i],"■");
     case 2: point_ex(pt.x[i],pt.y[i],"||");
     case 3: point_ex(pt.x[i],pt.y[i],"--");
     case 4:
      {
       ::SetConsoleTextAttribute(::GetStdHandle(STD_OUTPUT_HANDLE),7);
          point_ex(pt.x[i],pt.y[i],"○");
       ::SetConsoleTextAttribute(::GetStdHandle(STD_OUTPUT_HANDLE),14);
      }
    }
   }
   putchar(10);    
   //pic_debug();
}
void pic_copy(uchar*tx,uchar*ty,uchar *tz,int pnum)
{
    int i;
 if(pnum==0)   return;
 pt.pnum=pnum;
 for(i=0;i<pnum;i++)
 {
      pt.x[i]=tx[i];
   pt.y[i]=ty[i];
   pt.z[i]=tz[i];
 }
 return;
}
//--------整理pic-------
void  pic_sort(uchar*tx,uchar*ty,uchar *tz,int pnum)//在原来的插入排序法上,使ty的值跟着tx的值移动,对于pixel进行整理
{
    int h;
 int i,j,t,k;
 int m,n,l;
    if(pnum==0)   return;
 //----第一步排tx(并保持tx与ty之间的对应关系)---
 for(i=1;i<pnum;i++)//只对数组赋值的区域排序
 {
  t=tx[i];
  k=ty[i];h=tz[i];
  for(j=i-1;j>=0;j--)
   if(t<tx[j]) {  tx[j+1]=tx[j];ty[j+1]=ty[j];tz[j+1]=tz[j];  }
   else break;
  tx[j+1]=t;
  ty[j+1]=k;tz[j+1]=h;
 }
 //--------第二步逐行排ty----------
 for(i=tx[0],j=0;i<=tx[pnum-1];i++)//从第tx[0]到tx[p0.pnum-1]行 
 { 
  l=0;  //j的最大值不能超过p0.pnum
  while(tx[j]==i)
     //此处只依靠tx[*]的值去做判断,容易出现超出数组寻址范围的情况,因为如果对于未定义的内存空间(此处是明确的,tx后的地址就是ty的地址),其值虽然相对
  //不变,但总体(理论上)应该是不确定的(这可能取决于各自的机器),因此尽管超出规定的范围,仍然有可能
  //满足这个判别式,从而造成寻址越界的情况
  {  
            if(j==p0.pnum)   break;//后来加的限制条件,没有它会出现一系列的奇葩现象
   j++;l++;
  }//得到tx[*]行的点数l
  //当tx[*]全赋0且ty[0]=0,此处寻址越界,由于tx[*]寻址越界后,寻到了ty[*]处,他们地址是连续的,
  //而此时的ty[0]正好满足ty[0]=tx[0]=0,这就造成了寻址越界,因此加上一条限制语句(如上),
  //也证明上面的猜想是正确的
  if(l==1||l==0)  continue;
        //*************************************
  for(m=j-l;m<j-1;m++)
  {
   k=m;
   for(n=m+1;n<j;n++)
    if(ty[n]<ty[k])  k=n;
      if(k!=m)
   {
     t=ty[k];ty[k]=ty[m];ty[m]=t;//ty移动
     t=tz[k];tz[k]=tz[m];tz[m]=t;//随ty移动tz
   } 
  }
  //************************************
  //必须说明被*号拦起来的代码相当奇葩,其中明显可以发现,程序并没有对p0.pnum进行赋值,
     //但其值其出现了奇葩式的间断连续改变,这个或许和上面寻址越界有关,毕竟po0.x[*]、p0.y[*]、p0.pnum
  //定义在一起(同一个结构体中),它们的地址应该是连续的
 }
 //当p0.pnum=3200时,由于寻址越界,它被当作了ty来进行排序,由上面分析可知,当时j=3021,越界一位正好
 //p0.pnum被加进来了,由于是用ty[3200]的形式加进来的,所以它的类型就由int变为了char,可以计算3200/256=12.5
 //也就是说,经过12次循环后其值变为0.5*256=128,而由于是char型,其正数最大为127,对应于-128,此时最小
 //这也就是为什么会在pic_debug()中出现一个负数的原因,同时也解释了为什么将结构体PIC中数组改为uchar后,
 //又出现了正确的pic_debug()界面(其值最大被放到了最后,也就是没有变动)。
 //最后int型的p0.pnum排到了char型里,char型的9排到了int型里,由于p0.[3200]的方式只调走了int型内存区域的256以内(即一个字节内)的数值
 //还有12*256保留在原处,所以会出现p0.pnum=12*256+9=3081的情况,,到此所有的谜团都解开了。
 //而问题的关键仅仅是一个寻址越界造成的,现做两点修改:
 //1.加入如上所示的限制条件
 //2.将PIC结构体中的数组改为uchar,因为我们不打出负点
}
//----使用帮助
//1.先为结构体PIC赋值,将一个个要显示的点装入数组,不分先后无需排序,只要x,y对应正确即可
//2.更新p0.pnum为当前总共要显示的pixel数
//3.直接调用picture()即可
//4.对于picture()的调试,一般采用pic_debug()函数找出问题所在

{

 

    int num;

    char name[20];
    char sex;
    int age;
    float score;
    char addr[30];
    struct Date birthday;
}a={102,"zhangsan",'M',22,66.0,"123 shenzhen road"};
int main(int argc, char* argv[])
{
    printf("num:%dnname:%snsex:%cnage:%dnscore:%.2fn",a.num,a.name,a.sex,a.age,a.score);
    return 0;
}

-------------------------------- 作者在 2017-04-18 11:16:35 补充以下内容

数组指针:
#include<stdio.h>
 
int main()
{
     
   char c[][4] = {"哥", "哥", "我", "岸", "上", "走"};    //UTF-8:一个汉字=3个字节
 
   char (*p)[4];
   int i;    p=c;    //将指针定位于c[0]
    for(i=0;i<=5;i++)
    {
        printf("%s, ", *(p+i));  //或者将*(p+i)替换成*p++
    }
    printf("n");    
    for(i=5;i>=0;i--)
    {
        printf("%s,",*(p+i));    //或者将*(p+i)替换成*p--
    }
    return 0;
}
指针数组:

#include<stdio.h>
 
int main()
{
 
    int i;
  char *pch[6] = {"妹","妹","你","坐","船","头"};
    for(i=0;i<6;i++)
   {
        printf("%s, ",pch[i]); 
    } 
    printf("n"); 
    for(i=5; i>=0; i--)
   { 
        printf("%sn",pch[i]); 
    }
    return 0;
}

-------------------------------- 作者在 2017-04-18 11:17:23 补充以下内容

年月日判断

#include<stdio.h>

int main()
{
int year,mouth,day,sum,x;
    printf("年月日:");
scanf("%d,%d,%d",&year,&mouth,&day);
switch(mouth)
{
case 1: sum=0;break;
case 2: sum=31;break;
    case 3: sum=31+28;break;
case 4: sum=31+28+31;break;
case 5: sum=31+28+31+30;break;
case 6: sum=31+28+31+30+31;break;
case 7: sum=31+28+31+30+31+30;break;
case 8: sum=31+28+31+30+31+30+31;break;
case 9: sum=31+28+31+30+31+30+31+31;break;
case 10:sum=31+28+31+30+31+30+31+31+30;break;
case 11:sum=31+28+31+30+31+30+31+31+30+31;break;
case 12:sum=31+28+31+30+31+30+31+31+30+31+30;break;
    default:printf("ERROR!n");
}
x=sum+day;
if((year%400==0)||(year%4==0&&year%100!=0))
{
printf("%d年是闰年!n",year);
if(mouth>2)
{
x+=1;
}
}
else printf("%d年不是闰年!n",year);
printf("%d年%d月%d日是%d年的第%d天!n",year,mouth,day,year,x);
return 0;
}

-------------------------------- 作者在 2017-04-18 11:18:51 补充以下内容

十进制转换二进制函数

#include<stdio.h>

int main()
{
int a,i,j,b[1000];
printf("请输入要转换成2进制的整数:n");
scanf("%d",&a);
    for(i=0;;i++)
{
b[i]=a%2;
a=(int)((a*1.0)/2.0);
if(a==0)break;
}
for(j=i;j>=0;j--)
{
printf("%d",b[j]);
}

return 0;
}

-------------------------------- 作者在 2017-04-18 11:19:56 补充以下内容

输入-1时结束问题

#include<stdio.h>
int main()
{
int cj=0,he=0,i=0;
while(i<30)
{
scanf("%d",&cj);
            he+=cj;
if(cj==-1)break;
}
printf("%d",he+1);
return 0;
}

-------------------------------- 作者在 2017-04-18 11:22:08 补充以下内容

动态链表

#include<stdio.h>                            //头文件  
#include<malloc.h>                           //头文件  
#define LEN sizeof(struct Student)           //宏定义
struct Student                               //定义结构体
{   int num;                                 //定义num为整形变量
float score;                             //定义单精度变量score
struct Student * next;                   //指针变量next指向结构体
};                                           //结构体写完加";"表示结束
int n;                                       //全局变量n
struct Student * creat(void)                 //此函数返回一个指向链表头的指针
{   struct Student * head;                   //定义结构体类型指针变量head头指针
struct Student * p1,* p2;                //定义结构体类型指针变量p1,p2
n=0;                                     //n赋值0
p1=p2=(struct Student * ) malloc(LEN);   //用malloc函数开辟一个长度为LEN的新单元
scanf("%ld,%f",&p1->num ,&p1->score );   //输入付给num,score的值
head=NULL;                               //指针变量head不指向任何类型
while(p1->num !=0)                       //当指针p1指向num的值不为0时
{   n=n+1;                               //节点计数器
if(n==1) head=p1;                    //如果n=1为真,head指向p1
else p2->next =p1;                   //如果n=1为假,将下一个节点指向p1
p2=p1;                               //再将p2指向p1
p1=(struct Student *) malloc(LEN);   //用malloc函数开辟一个长度为LEN的新单元
scanf("%d,%f",&p1->num ,&p1->score );//输出p1
}
p2->next =NULL;                          //p2指向终点
return(head);                            //返回head
}
int main()                                   //主函数
{   struct Student * pt;                     //定义结构体类型指针变量pt
pt=creat();                              //调用函数creat,使pt指向该函数返回的指针变量
printf("nnum:%ldnscore:%5.1fn",pt->num ,pt->score );//输出pt
return 0;                                //结束
}

-------------------------------- 作者在 2017-04-18 11:23:16 补充以下内容

爱心程序

#include<stdio.h>
#include<math.h>
#include<windows.h>
#include<tchar.h>
float f(float x,float y,float z)
{
float a=x*x+9.0f/4.0f*y*y+z*z-1;
return a*a*a-x*x*z*z*z-9.0f/80.0f*y*y*z*z*z;
}
float h(float x,float z)
{
for(float y=1.0f;y>=0.0f;y-=0.001f)
if(f(x,y,z)<=0.0f)
return y;
return 0.0f;
}
int main(int argc,char * crgv[])
{
HANDLE o=GetStdHandle(STD_OUTPUT_HANDLE);
_TCHAR buffer[25][80]={ _T(' ') };
_TCHAR ramp[]=_T("-=+*#%@");
for(float t=0.1f;;t+=0.1f)
{
int sy=0;
float s=sinf(t);
float a=s*s*s*s*0.2f;
for(float z=1.3f;z>-1.2f;z-=0.1f)
{
_TCHAR* p=&buffer[sy++][0];
float tz=z*(1.2f+a);
for(float x=-1.5f;x<1.5f;x+=0.05f)
{
float tx=x*(1.2f+a);
float v=f(tx,0.0f,tz);
if(v<=0.0f)
{
float y0=h(tx,tz);
float ny=0.01f;
float nx=h(tx+ny,tz)-y0;
float nz=h(tx,tz+ny)-y0;
float nd=1.0f/sqrtf(nx*nx+ny*ny+nz*nz);
float d=(nx+ny-nz)*nd*0.5f+0.5f;
*p++=ramp[(int)(d*0.5f)];
}
else 
*p++=' ';
}
}
for(sy=0;sy<25;sy++)
COORD coord=(0,sy);
SetConsoleCursorPosition(o,coord);
WriteConsole(o,buffer[sy],79,NULL,0);
}
Sleep(33);
}
}

-------------------------------- 作者在 2017-04-18 11:24:48 补充以下内容

简单的链表应用
#include<stdio.h>
#include<malloc.h>
#define LEN sizeof(struct Student)
struct Student
{
int a;
char b[20];
struct Student * next;
}*head,*p1,*p2;
int n,x=0;;
struct Student * scan()
{
p1=p2=(struct Student *)malloc(LEN);
printf("输入学号,姓名:");
scanf("%d,%s",&p1->a,&p1->b);
while(p1->a!=NULL)
{
n=n+1;
if(n==1)head=p1;
else p2->next=p1;
p2=p1;
p1=(struct Student *)malloc(LEN);
printf("输入学号,姓名:");
scanf("%d,%s",&p1->a,&p1->b);
}
p2->next=NULL;
return (head);
}
void print(struct Student * head)
{
struct Student * p;
p=head;
printf("一共%d个信息:n",n);
if(head!=NULL)
do
{
x=x+1;
printf("序号:%d,学号:%d,姓名:%sn",x,p->a,p->b);
p=p->next;
}while(p!=NULL);
}
int main()
{
struct Student * head;
head=scan();
print(head);
    return 0;
}