c语言随笔1

@[TOC]c语言随笔

记录c语言听课笔记


一、使用啊哈c的system函数启动python

1.调用cmd命令打开python

在cmd中启动python找到python的安装路径然后输入start D:“Program Files (x86)”\python\python,便可以打开python
在这里插入图片描述

2.啊哈c中的system函数调用cmd命令打开python

打开啊哈c输入下面程序

#include <stdio.h>
#include <stdlib.h>
int main()
{
	system("start D:\\\"Program Files (x86)\"\\python\\python");
	system("pause");
	return 0;
}

点击运行即可实现
在这里插入图片描述
提示:由于文档路径中存在“”号\等需要加转义字符

二、判断学生成绩

1.对输入成绩取模运算然后使用case语句进行判断

打开啊哈c输入下面程序

#include <stdio.h>
#include <stdlib.h>
int main()
{
  /*  1.定义变量
	2.输入变量
    3.条件语句
    4.分支语句*/
    int score;
    int a;
    printf("请输入成绩\n");
    scanf("%d",&score);
    if(score==100)
    {
      printf("满分恭喜\n");
    }
    else
    {
     a=score/10;
     switch(a)
      {
       case 0:
       case 1:
       case 2:
       case 3:
       case 4:
       case 5:
       printf("你没及格\n");
       break;
       case 6:
       case 7:
       case 8:
       case 9:
       printf("你及格了;\n");
       break;
       default:
        printf("非法成绩\n");
        break;
      }
    }
	system("pause");
	return 0;
}

2.使用while循环语句和if-else语句进行判断

#include <stdio.h>
#include <stdlib.h>
int main()
{
    int score;
    int cishu=0;
	while(1)
    { 
       cishu = cishu + 1;
	   printf("请输入成绩:\n");
	   scanf("%d",&score);
		if(score>=90)
		{
		  printf("优秀\n");
		}
		else if(score<90 && score>=75)
		{
		 printf("良好\n");
		}
		else
		{
		 printf("垃圾\n");
		}
       if(cishu == 3)
       {
        break;
       }
    }
	system("pause");
	return 0;
}

3.使用for循环语句和if-else语句进行判断

#include <stdio.h>
#include <stdlib.h>
int main()
{
    int score;
    int i=0;
	for(i=0;i<=3;i++)
    { 
       
	   printf("请输入成绩:\n");
	   scanf("%d",&score);
		if(score>=90)
		{
		  printf("优秀\n");
		}
		else if(score<90 && score>=75)
		{
		 printf("良好\n");
		}
		else
		{
		 printf("垃圾\n");
		}
       
       
    }
	system("pause");
	return 0;
}

三,函数

1.函数中的形参

只有当函数体被调用时才申请了内存空间,有了变量同时空间内的数据被赋值成实际参数。函数执行结束后内存自动被释放,也就是形式参数仅作用于该函数是局部变量。

#include <stdio.h>
#include <stdlib.h>
void test(int a)
    {
		printf("%d\n",a);
        printf("test:a的地址%p\n",&a);
        a++;
        printf("%d\n",a);
    }    
int main()
{
	int a=30;
    test(a);
    printf("a=%d\n",a);
    printf("main:a的地址%p\n",&a);
	system("pause");
	return 0;
}

结果如下 当函数调用结束后a还是30,而且虚拟地址不同。
在这里插入图片描述

2.有返回值的函数中return的作用

使用return y;把函数执行的结果返回给调用者
第一种函数不加return的情况:

#include <stdio.h>
#include <stdlib.h>
int f(int x)
{
	int y;
    y=2*x+1;
    printf("y=%d\n",y);
}
int main()
{
	int y=0;
    int x=100;
    y=f(x);
    printf("main:y=%d\n",y);
	system("pause");
	return 0;
}

在这里插入图片描述
结果显示函数中的y与main中的y值不同,第二种函数加return的情况:

#include <stdio.h>
#include <stdlib.h>
int f(int x)
{
	int y;
    y=2*x+1;
    printf("y=%d\n",y);
    return y;
}
int main()
{
	int y=0;
    int x=100;
    y=f(x);
    printf("main:y=%d\n",y);
	system("pause");
	return 0;
}

在这里插入图片描述

3.使用函数实现选择加减乘除

第一种实现方法:

#include <stdio.h>
#include <stdlib.h>
void tips ()
{
   printf("请选择一种算法\n");  
}
int add (int x,int y)
{
  int z;
  z=x+y;
  return z;
}
int min (int x,int y)
{
  int z;
  z=x-y;
  return z;
}
float chufa (int x,int y)
{
  float z;
  z=(float)x/y;  //不同类型数据运算时,比如两个整数相除,必须将除数或被除数强制转换乘小数,否则小数点后的数据被忽略
  return z;
}
int mul (int x,int y)
{
  int z;
  z=x*y;
  return z;
}
int main()
{
   int x,y,z;
   float a;
   char suanfa;                     //+-*%字符
   while(1)
   {
    tips ();
    scanf("%c",&suanfa);            //%c对应字符 输入+-*%字符时接受
    getchar();                      //接收回车
    switch(suanfa)
    {
       case '+':                    //整数时case 1: 字符串时case '+':
       printf("你选择了加法\n");
       printf("请输入第一个数据\n");
       scanf("%d",&x);
       printf("请输入第二个数据\n");
       scanf("%d",&y);
       z=add(x,y);
       printf("加法结果%d+%d=%d\n",x,y,z);
       break;
       case '-':
       printf("你选择了减法\n");
       printf("请输入第一个数据\n");
       scanf("%d",&x);
       printf("请输入第二个数据\n");
       scanf("%d",&y);
       z=min(x,y);
       printf("减法结果%d-%d=%d\n",x,y,z);
       break;
       case '*':
       printf("你选择了乘法\n");
       printf("请输入第一个数据\n");
       scanf("%d",&x);
       printf("请输入第二个数据\n");
       scanf("%d",&y);
       z=mul(x,y);
       printf("乘法结果%d*%d=%d\n",x,y,z);
       break;
       case '/':
       printf("你选择了除法\n");
       printf("请输入第一个数据\n");
       scanf("%d",&x);
       printf("请输入第二个数据\n");
       scanf("%d",&y);
       a=chufa(x,y);
       printf("除法结果%d/%d=%f\n",x,y,a);
       break;
       default:
       break;
    }
	system("pause");
	return 0;
}

优化后:

#include <stdio.h>
#include <stdlib.h>
int add (int x,int y)
{
  int z;
  z=x+y;
  return z;
}
int min (int x,int y)
{
  int z;
  z=x-y;
  return z;
}
int mul (int x,int y)
{
  int z;
  z=x*y;
  return z;
}
float chufa (int x,int y)
{
  float z;
  z=(float)x/y;  //不同类型数据运算时,比如两个整数相除,必须将除数或被除数强制转换乘小数,否则小数点后的数据被忽略
  return z;
}
void tips ()
{
   printf("请选择一种算法\n");  
}
void realcacl(int x,int y,char suanfa)
{
    switch(suanfa)
    {
       case '+':
       printf("两数相加,结果:%d\n",add(x,y));
       break;
       case '-':
       printf("两数相减,结果:%d\n",min(x,y));
       break;
       case '*':
       printf("两数相乘,结果:%d\n",mul(x,y));
       break;
       case '/':
       printf("两数相除,结果:%f\n",chufa(x,y));
       break;
       default:
       break;
    }  
}
void  whichcacl(char suanfa)
{
   switch(suanfa)
    {
       case '+':
       printf("你选择了加法\n");
       break;
       case '-':
       printf("你选择了减法\n");
       break;
       case '*':
       printf("你选择了乘法\n");
       break;
       case '/':
       printf("你选择了除法\n");
       break;
       default:
       break;
    }
}
void cacl(char suanfa)
{
       int x,y;
       whichcacl(suanfa);
       printf("请输入第一个数据\n");
       scanf("%d",&x);
       printf("请输入第二个数据\n");
       scanf("%d",&y); 
       realcacl(x,y,suanfa);
       
}
int main()
{
   int x,y,z;
   float a;
   char suanfa;
   while(1)
   {
    tips ();
    scanf("%c",&suanfa);
    getchar();
    cacl(suanfa);
   }
	system("pause");
	return 0;
}

4.函数入口参数化为指针地址

#include <stdio.h>
#include <stdlib.h>
/*
void jiajiaA(int *p)       //int *p=&a 表示指针变量存放的a的地址
{
 *p=*p+1;
 printf("jia:a=%d\n",*p);
}
int main()
{
	int a=10;
    jiajiaA(&a);
    printf("a=%d\n",a);
	system("pause");
	return 0;
}
*/
/*
void swap(int a,int b)  //由于函数的形式参数等函数 调用结束之后就会释放所以a和b的值并没有交换
{
 int tmp;
 tmp=a;
 a=b;
 b=tmp;
}
int main()
    {
      int a=10;
      int b=5;
      swap(a,b);
      printf("a=%d\n",a);
      printf("b=%d\n",b);
      system("pause");
	  return 0;
    }
 */
 //解决方案
 void swap(int *a,int *b) 
{
 int tmp;
 tmp=*a;
 *a=*b;
 *b=tmp;
}
int main()
    {
      int a=10;
      int b=5;
      swap(&a,&b);
      printf("a=%d\n",a);
      printf("b=%d\n",b);
      system("pause");
	  return 0;
    }

5.函数指针

#include <stdio.h>
#include <stdlib.h>
void printfwc()
    {
      printf("欢迎来到c语言课堂\n");
    }
int add(int a,int b)
{
 return a+b;
}
int main()
{
	printfwc();
    //1.如何定义一个函数指针   1.如何表示指针:*  2.如何知道是函数:()  3.函数指针是专用的格式要求很强
    void (*p2)();
    //2.如何给函数指针赋值    函数名就是地址
    p2=printfwc;
    //3.如何通过函数指针调用函数
    p2();
    (*p2)();
    int (*padd)(int a,int b);
    padd=add;
    int ret;
    ret=padd(1,2);
    printf("结果:%d\n",ret);
	system("pause");
	return 0;
}

在这里插入图片描述

四,数组

重要概念
1.数组的定义:类型,数组名,数组大小。
2.数组是数据的集合,且是同类型数据内存空间连续。
3.数组的三种定义方式包括有初始化,不完整初始化和没有初始化,数组的名是数组的起始地址,不完整初始化的未定义数组元素默认为零。
4.数组元素根据下标进行索引,下标从0开始。
5.数组的中括号[]只有在定义时表示数组的大小,其余情况为数组元素的索引。
6.数组做实参时传递的是数组首地址

1.使用for循环遍历数组元素

#include <stdio.h>
#include <stdlib.h>
int main()
{   
	int array[3]={1,2,3};
    int array1[10]={0};
    int i;
    for(i=0;i<3;i++)
    {
      printf("数组中第%d个数据是:%d\n",i+1,array[i]);
    }
    printf("输入动态赋值数");
    scanf("%d",&array1[1]);           //数组元素动态赋值
    printf("array1[1]=%d",array1[1]);
	system("pause");
	return 0;
}

2.动态赋值数组并找出数组内的最值并计算出和,均值

#include <stdio.h>
#include <stdlib.h>
int main()
{
	int i;
    int max,min,total;
    float ave;
    int datas[10]={0};
    for(i=0;i<10;i++)
    {
      printf("请输入第%d个数:",i+1);
      scanf("%d",&datas[i]);
    }  
    for(i=0;i<10;i++)
    {
     printf("第%d个数据是:%d\n",i+1,datas[i]);       //数组元素动态赋值
    }
    max=datas[0];
    for(i=0;i<10;i++)   
    {
      if(max<datas[i])
      {
        max=datas[i];
      }
    } 
    printf("最大数据是:%d\n",max);
    min=datas[0];
    for(i=0;i<10;i++)   
    {
      if(min>datas[i])
      {
        min=datas[i];
      }
    } 
    printf("最小数据是:%d\n",min); 
    total=0;
    for(i=0;i<10;i++)
    {
     total=total+datas[i];
    }
    ave=(float)total/10;           //强制转化数据类型
    printf("数组之和是:%d\n",total); 
    printf("数组平均值是:%f\n",ave); 
	system("pause");
	return 0;
}

3.函数传参打印数组元素并打印整形数组和字符数组的大小

#include <stdio.h>
#include <stdlib.h>
//数组与函数结合 第一个参数是数组首地址 第二个是数组元素个数
void arrayprint(int datas[],int cnt)//在这里的cnt是因为形式参数中的数组传的是一个地址大小不代表数组的大小
    {
     int i;
     for(i=0;i<cnt;i++)
     {
      printf("%d",datas[i]);
      putchar('\n');
     }
    }
int main()
{
	int array[3]={11,22,38};//当数组不完全赋值时打印出来会是0
    arrayprint(array,sizeof(array)/sizeof(array[0]));
    //arrayprint(&array[0],sizeof(array)/sizeof(array[0]));两种写法等效
    int a[3];                                         //一个整形占用4个字节 3x4=12
    char b[3];                                        //一个字符型占用1个字节 3x1=3
    printf("a数组的大小是;%d\n",sizeof(a));
    printf("b数组的大小是;%d\n",sizeof(b));
    printf("一个整型的大小是;%d\n",sizeof(int));
    printf("一个字符的大小是;%d\n",sizeof(char));
    printf("a数组有%d个元素\n",sizeof(a)/sizeof(a[0]));
    printf("b数组有%d个元素\n",sizeof(b)/sizeof(b[0]));
	system("pause");
	return 0;
}

执行结果可以看出结论数组类型不同数组大小也不同
在这里插入图片描述

4.函数封装找学生最高分最低分和平均分数组实现

#include <stdio.h>
#include <stdlib.h>
//初始化数组
void initScores(int scores[],int size)
{
 int i;
 for(i=0;i<size;i++)
    {
      printf("请输入第%d个学生的分数:",i+1);
      scanf("%d",&scores[i]);
    }  
}
//打印数组
void printfScores(int scores[],int size)
{
  int i;
  for(i=0;i<size;i++)
    {
     printf("第%d个学生成绩是:%d\n",i+1,scores[i]);
    }
}
//遍历数组获取最高分
int getMax(int scores[],int size)
{
  int max,i;
  max=scores[0];
    for(i=0;i<size;i++)   
    {
      if(max<scores[i])
      {
        max=scores[i];
      }
    }
      return max;
}
//遍历数组获取最低分
int getMin(int scores[],int size)
{
  int min,i;
  min=scores[0];
    for(i=0;i<size;i++)   
    {
      if(min>scores[i])
      {
        min=scores[i];
      }
    }
      return min;
}
//遍历数组的到平均值
float getAve(int scores[],int size)
{
   int total=0;
   int i;
   float ave;
    for(i=0;i<size;i++)
    {
     total=total+scores[i];
    }
    ave=(float)total/10;
    return ave;
}
void printfset(int data1,int data2,float data3)
{
  printf("最高值是:%d\n,最低值是:%d\n,平均值是:%f\n",data1,data2,data3);
}
int main()
{
	int scores[10];
    int len,max,min;
    float ave;
    len=sizeof(scores)/sizeof(scores[0]);
    initScores(scores,len);
    printfScores(scores,len);
    max=getMax(scores,len);
    min=getMin(scores,len);
    ave=getAve(scores,len);
    printfset(max,min,ave);
	system("pause");
	return 0;
}

5.数组指针的偏移

#include <stdio.h>
#include <stdlib.h>
int main()
{
	int a[3]={1,2,3};
    int b;
    int (*p)[3];  //数组指针 与之前不同该指针的偏移量是3*4=12个字符
    p=a;
    int *p2;
    p2=a;
    printf("数组的地址是%p\n",a);
    printf("数组的地址是%p\n",&a[0]);
    printf("p数组的地址是%p\n",p);
    printf("p2数组的地址是%p\n",p2);
    printf("----------区别-------------\n");
    printf("p++的结果是:%p\n",++p);
    printf("p2++的结果是:%p\n",++p2);
	system("pause");
	return 0;
}

在这里插入图片描述

五,字符串

#include <stdio.h>
#include <stdlib.h>
int main()
{
    int i;
	char str[5]={'a','b','c','d','e'};
    for(i=0;i<sizeof(str)/sizeof(str[0]);i++)
    {
     printf("%c",str[i]);
    }
    printf("\n");
    
    char str2[5]="abcde";
    for(i=0;i<sizeof(str2)/sizeof(str2[0]);i++)
    {
     printf("%c",str2[i]);
    }
    printf("\n");
    char str3[]="abcdefghijkl";
    for(i=0;i<sizeof(str3)/sizeof(str3[0]);i++)
    {
     printf("%c",str3[i]);
    }
    printf("\n");
    char (*pstr)[]="hello world";
    printf("%s",pstr);
    printf("\n");
	system("pause");
	return 0;
}

在这里插入图片描述

1.字符串存储方式

#include <stdio.h>
#include <stdlib.h>
int main()
{
	int a[3]={1,2,4};
    printf("a数组的大小是:%d\n",sizeof(a));
    printf("数组元素的大小是:%d\n",sizeof(a[0]));
    printf("数组元素的大小是:%d\n",sizeof(int));
    printf("数组的个数是:%d\n",sizeof(a)/sizeof(a[0]));
    char a2[3]={'a','b','c'};
    printf("a数组的大小是:%d\n",sizeof(a2));
    printf("数组元素的大小是:%d\n",sizeof(a2[0]));
    printf("数组元素的大小是:%d\n",sizeof(char));
    printf("数组的个数是:%d\n",sizeof(a2)/sizeof(a2[0]));
     char a3[3]="abc";                                        //该结果数组大小是3
    printf("a数组的大小是:%d\n",sizeof(a3));
    printf("数组元素的大小是:%d\n",sizeof(a3[0]));
    printf("数组元素的大小是:%d\n",sizeof(char));
    printf("数组的个数是:%d\n",sizeof(a3)/sizeof(a3[0]));
    char a4[]="abc";                                          //该结果数组大小是4 多了一个\0代表字符串的结束标志
    printf("a数组的大小是:%d\n",sizeof(a4));
    printf("数组元素的大小是:%d\n",sizeof(a4[0]));
    printf("数组元素的大小是:%d\n",sizeof(char));
    printf("数组的个数是:%d\n",sizeof(a4)/sizeof(a4[0]));
    printf("%s\n",a4);
    int i=0;
    while(a4[i] !='\0')
    {
     printf("%c",a4[i]);
     i++;
    }
	system("pause");
	return 0;
}

在这里插入图片描述

2.字符串复制

#include <stdio.h>
#include <stdlib.h>
int main()
{
	//char strdest[128]={'\0'};          用复制函数时可以将第一参数变为数组也可用指针
    char *strdest;                       //下边这种写法等价于第一种写法
    strdest=(char *)malloc(128);
    if (strdest==NULL)
    {
     printf("申请失败\n");
     exit(-1);
    }
    memset(strdest,'\0',128);
    char *strsrc="嵌入式必须拿下";
    strcpy(strdest,strsrc);             //字符串复制将第二参数复制到第一参数里  原型strcpy(char *dest,char *dest1);参数都是指针
    printf("复制字符串完毕\n");
    puts(strdest);
    memset(strdest,'\0',sizeof(strdest)/sizeof(strdest[0]));
    strcpy(strdest,"ssbjkd");
    puts(strdest);
    memset(strdest,'\0',sizeof(strdest)/sizeof(strdest[0]));
    strncpy(strdest,"ssbjkd",1);
    puts(strdest);
    char test[128]="我爱嵌入式";
    strcat(test,strsrc);                 //字符串结合函数
    puts(test);
    char *str1="123";
    char *str2="123";
    /*
    int ret=strcmp(str2,str1);
    printf("ret=%d\n",ret);
    if(ret==0)
    {
     printf("两个字符串里的内容相同\n");
    }
    */
    if(strcmp(str2,str1)==0)
    {
     printf("两个字符串里的内容相同\n");
    }
	system("pause");
	return 0;
}

在这里插入图片描述

3.字符串中野指针

#include <stdio.h>
#include <stdlib.h>
int main()
{
    char *pstr;
    pstr=(char*)malloc(128);
    if(pstr==NULL)
    {
     printf("申请失败");
     exit(-1);
    }
    memset(pstr,'\0',128);
    printf("请输入字符\n");
    gets(pstr);
    puts(pstr);
	system("pause");
	return 0;
}

在这里插入图片描述

4.自己创建puts

#include <stdio.h>
#include <stdlib.h>
void myputs(char*p)
    {
     while(*p !='\0')
     {
      putchar(*p++);
     }
     putchar('\n');
    }
int mygets(char *p)
{
  int cnt=0;
  if (p==NULL)
  {
   printf("内存非法");
   return;
  }
  while(*p=getchar())
  {
   if(*p=='\n')
   {
    return cnt;
   }
   else
   {
    cnt++;
    p++;
   }
  }
 }
 int mystrlen(char *str)
 {
  int cnt=0;
  while(*str++ !='\0')    //也要见识一下这种写法 
  {
   cnt++;
  // str++;
  }
  return cnt;
 }
 //char *strcpy(char * dest,char *src)
 void mymemset(char *p,char c,int size)
 {
   while(size)
   {
    *p++=c;
    size--;
   }
 }
int main()
{
    //char str[128]={'\0'};
	char *p="woxihuanqianrushi";
    char *str=NULL;
    str=(char *)malloc(128);
    //memset(str,'a',128);
    mymemset(str,'v',128);
    str[128]='\0';
    myputs(str);
    //printf("长度:%d\n",strlen(p));
    printf("长度:%d\n",mystrlen(p));
    myputs(p);
    myputs("请输入你的字符串:\n");
    int n=mygets(str);
    printf("你输入的字节数是:%d\n",n);
    mygets(str);
    myputs(str);
	system("pause");
	return 0;
}

在这里插入图片描述

5.自己创建字符串功能函数

#include <stdio.h>
#include <stdlib.h>
char *mystrcpy(char *dest,const char *src)
{
 if(dest==NULL||src==NULL)
 {
  return NULL;
 }
 while(*src!='\0')
  {
   *dest++=*src++;  //与下面的相同
   /*dest++;
   src++;*/
  }
  *dest='\0';
  return dest;
}
char *mystrncpy(char *dest,const char *src,int n)
{
 if(dest==NULL||src==NULL)
 {
  return NULL;
 }
 while(*src!='\0' && n>0)
  {
   *dest++=*src++;  
   n--;
  }
  *dest='\0';
  return dest;
}
void mystrcat(char *dest,char *src)
{
  while (*dest !='\0')
   {
    dest++;
   }
   while (*src !='\0')
    {
     *dest++=*src++;
    }
    *dest='\0';
}
int main()
{
	char dest[128]="hello";
    char *src="this is a test";
    //strcpy(dest,src);
    /*
    mystrcpy(dest,src);
    puts(dest);
    mystrncpy(dest,src,4);
    puts(dest);
    */
    //strcat(dest,src);
    mystrcat(dest,src);
    puts(dest);
	system("pause");
	return 0;
}

在这里插入图片描述

6.strlen字符串计算

#include <stdio.h>
#include <stdlib.h>
//不能用sizeof来计算字符串中有效字符的个数,应该用strlen他在计算时遇到\0就会结束计算
int main()
{
	char a[128]="hello";
    char *str="学习嵌入式很有趣";
    printf("数组a2的元素个数是:%d\n",sizeof(a)/sizeof(a[0]));
    printf("数组a2的真是元素个数是:%d\n",strlen(a));
    puts(str);
    printf("%s\n",str);
    char *pstr;                        // 野指针会造成非法内存访问  不能在野指针内写东西必须给他开辟空间 也就是malloc
    //char pstr[128]={'\0'};           1.申请了空间 2.初始化为\0
    pstr=(char*)malloc(128);           //只申请了空间    一旦用了malloc就要注意内存泄漏 要对返回值进行判断
    if(pstr==NULL)
    {
      printf("申请内存失败\n");
      exit(-1);
    }
    memset(pstr,'\0',128);              //1参数一初始化对象 2初始值 3大小
    printf("请输入字符串:\n");
    //scanf("%s",pstr);
    gets(pstr);
    puts(pstr);
	system("pause");
	return 0;
}

在这里插入图片描述

六,指针

#include <stdio.h>
#include <stdlib.h>
int main()
{
	int juhua=10;
    int meigui=9;
    int a=10;
    int b=100;
    int *p=&a;  //初始化一个指针变量    
    int *p2;
    p2=&b;      //给指针变量赋值  *p=&b是错误的 只有在初始化指针时才是指针标识符其余情况都是取内容运算符
    int *p1;
    p1=&juhua;
    int *p3=&meigui;
    printf("ju=%d\n",juhua);
    printf("mei=%d\n",meigui);
    printf("ju的地址是:%p\n",p1);  //&取变量名所对应的地址
    printf("mei的地址是:%p\n",p3);
    printf("通过地址来获取ju=%d\n",*(&juhua));
    printf("通过地址来获取ju=%d\n",*(&meigui));
    /*printf("通过地址来获取ju=%d\n",*p1);  //*取出后面地址中的内容
    printf("通过地址来获取mei=%d\n",*p3);*/
	system("pause");
	return 0;
}

在这里插入图片描述

1.指针类型++

#include <stdio.h>
#include <stdlib.h>
int main()
{
	int *p;
    char *p2;
    int a=10;
    char c='A';
    int array[3]={1,2,3};  //数组关心的是首地址 两种表示方式:1.数组名=地址 2.第一个元素的地址
    p=&a;
    p2=&c;
    printf("a=%d\n",*p);
    printf("c=%c\n",*p2);
    printf("a的地址为:%p\n",p);
    printf("a的地址++为:%p\n",++p);
    printf("c的地址为:%p\n",p2);
    printf("c的地址++为:%p\n",++p2);
    /*
    printf("数组中第一个元素地址为:%p\n",&array[0]);
    printf("数组中第二个元素地址为:%p\n",&array[1]);
    printf("数组中第三个元素地址为:%p\n",&array[2]);
    */
    int *parray;
    int i;
    parray=&array[0];
    for (i=0;i<3;i++)
    {
     printf("%d",array[i]);
    }
    printf("\n");
    /*
    printf("数组中第一个元素地址为:%p\n",parray++);  //p++先用后自加
    printf("数组中第二个元素地址为:%p\n",parray++);
    printf("数组中第三个元素地址为:%p\n",parray);
    */
    for(i=0;i<3;i++)
    {
     printf("%d",*parray);
     parray++;
    }
    printf("\n");
	system("pause");
	return 0;
}

在这里插入图片描述

2.指针入口参数成绩

#include <stdio.h>
#include <stdlib.h>
void initScores(int *scores,int size)
{
 int i;
 for(i=0;i<size;i++)
    {
      printf("请输入第%d个学生的分数:",i+1);
      scanf("%d",scores++);                  //优化二:由于参数中已经初始化定义了指针 则这个地方的地址用指针代替
    }  
}
void printfScores(int *scores,int size)
{
  int i;
  for(i=0;i<size;i++)
    {
     printf("第%d个学生成绩是:%d\n",i+1,*scores++);  //*scores++是左结合运算 先 *scores 后++
    }
}
int getMax(int *scores,int size)
{
  int max,i;
  max=*scores;          //*scores表示取出scores地址中的值
    for(i=0;i<size;i++)   
    {
      if(max<*scores)
      {
        max=*scores;
      }
      scores++;
    }
      return max;
}
int getMin(int *scores,int size)
{
  int min,i;
  min=*scores;
    for(i=0;i<size;i++)   
    {
      if(min>*scores)
      {
        min=*scores;
      }
      scores++;
    }
      return min;
}
float getAve(int *scores,int size)
{
   int total=0;
   int i;
   float ave;
    for(i=0;i<size;i++)
    {
     total=total+*scores;
     scores++;
    }
    ave=(float)total/10;
    return ave;
}
void printfset(int data1,int data2,float data3)
{
  printf("最高值是:%d\n,最低值是:%d\n,平均值是:%f\n",data1,data2,data3);
}
int main()
{
	int scores[10];
    int len,max,min;
    float ave;
    len=sizeof(scores)/sizeof(scores[0]);
    //initScores(scores,len);                 //函数调用中,传参就是一个赋值的过程!实际参数的值给形式参数   用数组名代表数组地址
    initScores(&scores[0],len);               //用数组第一元素取地址来代表数组首地址  两者实现结果相同
    printfScores(scores,len);
    max=getMax(scores,len);
    min=getMin(scores,len);
    ave=getAve(scores,len);
    printfset(max,min,ave);
	system("pause");
	return 0;
}

3.指针数组

#include <stdio.h>
#include <stdlib.h>
int main()
{
	int a=2;
    int b=3;
    int c=4;
    int array[3];
    int *p[3];
    int *parray[3];   //多个指针叫做指针数组,数组中的每一项都是一个指针变量,指针变量是存放数组的变量
    parray[0]=&a;
    parray[1]=&b;
    parray[2]=&c;
    int i;
    for(i=0;i<3;i++)
    {
      printf("%d",*(parray[i]));  //这里的括号表示运算优先级
    }
    printf("\n");
	system("pause");
	return 0;
}

4.用指针在确定地址放入确定数值

#include <stdio.h>
#include <stdlib.h>
int main()
{
	//将a=10强制存放在我想要的地址内 0x0060ff00
    int *p=(int*)0x0060ff00;
    *p=10;
    printf("在内存的%p位置,存放值%d\n",p,*p);
	system("pause");
	return 0;
}

在这里插入图片描述

5.无类型指针规定空间的大小

#include <stdio.h>
#include <stdlib.h>
int main()
{
	int n;
    printf("请输入你整型数组的元素总个数\n");
    scanf("%d",&n);
    printf("n=%d\n",n);
    int *parray=(int *)malloc(n*sizeof(int));
    int i;
    for (i=0;i<n;i++)
    {
      printf("请输入第%d个学生的成绩:\n",(i+1));
      scanf("%d",&parray[i]);
    }
    for (i=0;i<n;i++)
    {
     printf("第%d个学生的成绩是%d\n",(i+1),*parray++);
    }
	system("pause");
	return 0;
}

在这里插入图片描述

七,结构体

#include <stdio.h>
#include <stdlib.h>
struct student
{
 int score;
 char name[128];
};
int main()
{
    int a=10;
    struct student stu1={98,"丁毅"};
    printf("a=%d\n",a);
    printf("结构体:score=%d\n",stu1.score);
    printf("结构体:name=%s\n",stu1.name);
    struct student text;
    text.score=100;
    strcpy(text.name,"飞达");
    printf("结构体:score=%d\n",text.score);
    printf("结构体:name=%s\n",text.name);
	system("pause");
	return 0;
}

在这里插入图片描述

#include <stdio.h>
#include <stdlib.h>
void func(int data)
{
 printf("函数:data=%d\n",data);
}
struct Datas
{
 int a;
 char c;
 float f;
 double d;
 char str[128];
 void (*p)(int a);
};
int main()
{
	int a=10;
    printf("a=%d\n",a);
    char c='M';
    printf("c=%c\n",c);
    float f=1.2;
    printf("f=%f\n",f);
    double d=3.4;
    printf("d=%lf\n",d);
    //char *str="学习使我快乐";  初始化可以用指针变量指向字符串
    char *str;                  //野指针
    str=(char *)malloc(128);
    memset(str,'\0',28);
    strcpy(str,"学习使我快乐");
    puts(str);
    puts("--------------------------------");
    void (*p)(int data)=func;   //函数指针
    p(10);
    struct Datas d1;
    d1.a=100;
    d1.c='d';
    d1.f=3.44;
    d1.d=123.456;
    strcpy(d1.str,"学习使我快乐");
    d1.p=func;
    printf("d1.a=%d\n",d1.a);
    printf("d1.c=%c\n",d1.c);
    printf("d1.f=%f\n",d1.f);
    printf("d1.d=%lf\n",d1.d);
    puts(d1.str);
    d1.p(10);
	system("pause");
	return 0;
}

在这里插入图片描述

1.结构体指针

#include <stdio.h>
#include <stdlib.h>
struct Student
{
 int score;
 char name[128];
};
int main()
{
	struct Student stu1;
    stu1.score=100;
    strcpy(stu1.name,"张三");
    printf("名字:%s,分数:%d\n",stu1.name,stu1.score);
    struct Student *p;                                         //野指针记得开辟空间以及初始化
    // p.score=100                                             如果用结构体指针,就不能用点运算符访问结构体中的变量 要用->
    p=(struct Student *)malloc(sizeof(struct Student));        //注意malloc内的大小是一个结构体变量的大小  
    p->score=100;
    strcpy(p->name,"飞达");
    printf("名字:%s,分数:%d\n",p->name,p->score);
    free(p);                                                   //将开辟的空间释放掉 用于指向下一个地址
    p=&stu1;                                                   //第17行p指向malloc开的空间 该行指向stu1的地址
    printf("名字:%s,分数:%d\n",p->name,p->score);
    printf("地址是:%p\n",p++);
    printf("偏移后的地址是:%p\n",p);
	system("pause");
	return 0;
}

在这里插入图片描述

2.结构体指针成绩管理

#include <stdio.h>
#include <stdlib.h>
struct Student
{
 int score;
 char *name;
};
int main()
{
	int i;
    int len=0;
    printf("请输入总人数:\n");
    scanf("%d",&len);
    
    struct Student stus[len];
    struct Student *p=stus;
    for(i=0;i<len;i++)
    {
     printf("请输入名字:\n");
     p->name=(char *)malloc(128);
     scanf("%s",p->name);
     printf("请输入分数:\n");
     scanf("%d",&(p->score));
     p++;                                          //结构体指针偏移
    }
    p=p-len;
    for(i=0;i<len;i++)
    {
     printf("名字:%s,分数:%d\n",p->name,p->score);
     p++;
    }
	system("pause");
	return 0;
}

3.结构体指针成绩函数封装

#include <stdio.h>
#include <stdlib.h>
struct Student
{
 int score;
 char *name;
};
struct Student* initStuscore(int len)
    {
     int i;
   /*struct Student stus[len];
    struct Student *p=stus;  */
   struct Student *p=(struct Student *)malloc(len*sizeof(struct Student));
    for(i=0;i<len;i++)
    {
     printf("请输入名字:\n");
     p->name=(char *)malloc(128);
     scanf("%s",(p->name));
     printf("请输入分数:\n");
     scanf("%d",&(p->score));
     p++;                                          //结构体指针偏移
    }
    return p-len;
    }
struct student* findMaxscore(struct Student *p,int len)
    {
     int i;
        struct Student *max;
        max=p;
		 for(i=0;i<len;i++)
		{
		 if(max->score < p->score)
         {
          max=p;
         }
		 p++;                                          
		}
        return max;
    }
struct student* findMinscore(struct Student *p,int len)
    {
     int i;
     struct Student *min;
        min=p;
		 for(i=0;i<len;i++)
		{
		 if(min->score > p->score)
         {
          min=p;
         }
		 p++;                                          
		}
        return min;
    }
void printfMes(struct Student *p,int len)
    {
        int i;
		 for(i=0;i<len;i++)
		{
		 printf("名字:%s,分数:%d\n",p->name,p->score);
		 p++;
		}
    }
 float ave(struct Student *p,int len)
     {
      int i;
      int total=0;
      for(i=0;i<len;i++)
      {
       total+=p->score;
       p++;
      }
      return (float)total/len;
     }
int findsomeonename(struct Student *p,int len,char  *name)
{
 int i;
 for(i=0;i<len;i++)
 {
  if(strcmp(name,p->name)==0)
  {
   return 1;
  }
  p++;
 }
 return -1;
}
int main()
{
    int len=0;
    printf("请输入总人数:\n");
    scanf("%d",&len);
    struct Student *min=NULL;
    struct Student *max=NULL;
	struct Stdent *pstus=initStuscore(len);
    printfMes(pstus,len);
    min=findMinscore(pstus,len);
    max=findMaxscore(pstus,len);
    printf("min:%s,%d\n,max:%s,%d\n,ave:%f\n",min->name,min->score,max->name,max->score,ave(pstus,len));
    if(findsomeonename(pstus,len,"li")==-1)
    {
     printf("没有此人\n");
    }
    else 
    {
     printf("恭喜找到此人\n");
    }
	system("pause");
	return 0;
}

八 ,链表贪吃蛇

#include<stdio.h>
#include<stdlib.h>                                     //malloc和free
struct Test
{
 int data;
 struct Test *next;
};
void printfLink(struct Test *head)
{
  struct Test *point;
  point=head;
  
 while(1)
  {
   if(point!=NULL)
     { 
       printf("%d",point->data);
       point=point->next;
     }else
          {
           putchar('\n');
           break;
          }
  }
}
int getLinkTotalNum(struct Test *head)
{
 int cnt=0;
 struct Test *p=head;
 while(p!=NULL)
   {
    cnt++;
    p=p->next;
   }
   return cnt;
}
int searchLink(struct Test *head,int data)
  {
    
   while(head!=NULL)
     {
      if(head->data==data)
       {
        return 1;
       }
      head=head->next;
     }
     return 0;
  }
int gaiLink(struct Test *head,int data,int newdata)
  {
   while(head!=NULL)
     {
      if(head->data==data)
       {
        head->data=newdata;
        return 1;
       }
      head=head->next;
     }
     return 0;
  }
int insertFromBehind(struct Test *head,int data,struct Test *new)           //在某節點之後添加新節點
{
  struct Test *p=head;
   while(p!=NULL)
   {
    if(p->data==data)
      {
       new->next=p->next;             //新结点的下个地址给了4
       p->next=new;                   //4节点的地址给了新
       return 1;
      }
      p=p->next;
   }
   return 0;
}
struct Test* insertFromfor(struct Test *head,int data,struct Test *new)     //返回值是指針  在某節點之前添加新節點
{
  struct Test *p=head;
  if(p->data==data)                                                         //情況一:添加的節點在鏈表頭
    {
      new->next=head;
      return new;                                                           //注意return的意義
    }
     while (p->next!=NULL)
     {
       printf("data=%d,point=%d\n",p->next->data,data);
       if(p->next->data==data)
      {
        new->next=p->next;                     //新的下一個=p的下一個
        p->next=new;                           //p的下一個=新            這兩句話相當於在p   和p的下一個中間 放了一個new
        printf("insert ok\n");
        return head;
      }                                        //p  new   p->next的數據就是要求的數據 即在某數據前插入新節點的那個
      p=p->next;
     }
   printf("no this data%d\n",data);
   return head;
}
struct  Test* deletNode(struct Test *head,int data)      //刪除節點
{
  struct Test *p=head;
  if(p->data==data)
    {
       head=head->next;                                 //之所以用head不用p是因爲 p需要向下一個next指向 而head代表的就是鏈頭
       free(p);                                         //free只能釋放malloc的地址內存
       return head;                                     //當要刪除的是第一個節點時 刪除後返回頭
    }
    while(p->next!=NULL)
    {
      if(p->next->data==data)
      {
        p->next=p->next->next;
        return head;                                    //當要刪除的節點在中間被找到時刪除後返回頭
      }
      p=p->next;
    }
    return head;                                        //當找不到要刪除的節點時返回頭
}
struct Test* insertFromHead(struct Test *head,struct Test *new)          //頭插法
{
    if(head==NULL)
    {
      head=new;
    }else{
          new->next=head;
          head=new;
    }
  return head;
}
struct Test* createLink(struct Test *head)
{
  struct Test *new;
  while(1)
  {
    new=(struct Test*)malloc(sizeof(struct Test));
    printf("input your new node data\n");
    scanf("%d",&(new->data));
    if(new->data==0)
    {
      printf("0 out\n");
      free(new);
      return head;
    }
    head=insertFromHead(head,new);
  }
}
struct Test* insertBehind(struct Test *head,struct Test *new)   //尾插法
{
  struct Test *p=head;
  if(p==NULL)
  {
    head=new;
    return head;
  }
  while(p->next!=NULL)
  {
    p=p->next;
  }
  p->next=new;                                                 //將尾巴的NULL改爲new 即爲在尾巴上插入                                      
  return head;
}
struct Test* createLink2(struct Test *head)
{
  struct Test *new;
  while(1)
  {
    new=(struct Test*)malloc(sizeof(struct Test));
    printf("input your new node data\n");
    scanf("%d",&(new->data));
    if(new->data==0)
    {
      printf("0 out\n");
      free(new);
      return head;
    }
    head=insertBehind(head,new);
  }
}
int main()
{
  struct Test *head =NULL;
  //head=createLink(head);                       頭插法 出現的結果爲54321
  head=createLink2(head);                        //尾插法 結果爲12345
  printfLink(head);
  struct Test t1 ={100,NULL};
  head=insertFromHead(head,&t1);
  printfLink(head);
  struct Test t2 ={200,NULL};
  head=insertBehind(head,&t2);
  printfLink(head);
  /*
 int array[]={1,2,3};
 int i;
for(i=0;i<sizeof(array)/sizeof(array[0]);i++)
 {
   printf("%d",array[i]);
 }
putchar('\n');
*/
 //struct Test t1={1,NULL};
 /*
 struct Test *p=(struct Test*)malloc(sizeof(struct Test));
 struct Test t2={2,NULL};
 struct Test t3={3,NULL};
 struct Test t4={4,NULL};
  //t1.next=&t2;
  p->data=1;
  p->next=&t2;
  t2.next=&t3;
  t3.next=&t4;
  //head=&t1;
  head=p;
  printfLink(head);
  head=deletNode(head,4);
  printfLink(head);
  */
  /*
 struct Test new={100,NULL};
  printf("use t1 to printf three nums\n");
 // printf("%d,%d,%d\n",t1.data,t1.next->data,t1.next->next->data,t1.next->next->next->data));
  printfLink(head);
  int ret =getLinkTotalNum(head);
  printf("total num=%d\n",ret);
/*
  ret=searchLink(&t1,1);
  if(ret==0)
    {
      printf("no 1\n");
    }else{
          printf("have 1\n");  
         }
*/
/*
   puts("after insert behind:\n");
   insertFromBehind(head,3,&new);
   printfLink(head);
   struct Test new2={120,NULL};
   head=insertFromfor(head ,1,&new2);
   puts("after insert head:\n");
   printfLink(head);
   struct Test new3={130,NULL};
   head=insertFromfor(head ,1,&new3);
   puts("after insert for:\n");
   printfLink(head);
   */
return 0;
}

#include<curses.h>
#include<unistd.h>                                         //sleep和usleep
#include<pthread.h>                                        //線程
#include<stdlib.h>                                         //malloc函數需要使用該頭文件
#define UP       1
#define DOWN    -1
#define LEFT     2
#define RIGHT   -2
struct Snake
{
     int hang;
     int lie;
     struct Snake *next; 
};
struct Snake *head=NULL;
struct Snake *tail=NULL;
int key,dir;
struct Snake food;
void initFood()
{
     int x=rand()%20;                                        //对20取余值在0-19
     int y=rand()%20;
     food.hang=x;
     food.lie=y;
}
void initNcurse()
{
   initscr();                                              //ncurse界面初始化函數
   keypad(stdscr,1);
   noecho();
}
int hasSnakeNode(int i,int j)                              //想要打印蛇的其他節點 使用遍歷鏈表
{
     struct Snake *p;
     p=head;
     while(p!=NULL)
     {
          if(p->hang==i && p->lie==j)
          {
               return 1;
          }
          p=p->next;
     }
     return 0;
}
int hasFood(int i,int j)
{
     if(food.hang==i && food.lie==j)
     {
          return 1;
     }
     return 0;
}
void gamePic()
{
   int hang;
   int lie;
   move(0,0);                                   //移動光標實現貪吃蛇在一張圖上移動
   for(hang=0;hang<20;hang++)
      {
          if(hang==0)
          {
               for(lie=0;lie<20;lie++)
               {
                    printw("--");
               }
               printw("\n");                   //此處換行了 因此多了一行
          }
          if(hang>=0 && hang<20)               //0-19  共20個豎也即20行加上上一個換行一共21行
          {
             for(lie=0;lie<=20;lie++)
               {
                    if(lie==0 || lie==20)
                    {
                      printw("|");
                    }
                    else if(hasSnakeNode(hang,lie))
                    {
                         printw("[]");
                    }
                    else if(hasFood(hang,lie))
                    {
                         printw("##");
                    }
                    else
                    {
                      printw("  ");
                    }
               }
               printw("\n");                   //又換行了 光標起始位爲22行
          }
          if(hang==19)
          {
            for(lie=0;lie<20;lie++)
               {
                    printw("--");
               }
               printw("\n");
               printw("by yqh,food.hang=%d,foood.lie=%d",food.hang,food.lie);
          }
      }
}
void addNode()
{
     struct Snake *new=(struct Snake *)malloc(sizeof(struct Snake));
     new->next=NULL;
     switch(dir)
     {
          case UP:
               new->hang=tail->hang-1;
               new->lie=tail->lie;
               break;
          case DOWN:
               new->hang=tail->hang+1;
               new->lie=tail->lie;
               break;
          case LEFT:
               new->hang=tail->hang;
               new->lie=tail->lie-1;
               break;
          case RIGHT:
               new->hang=tail->hang;
               new->lie=tail->lie+1;
               break;
     }
     tail->next=new;                                           //尾巴的下一個指向新節點
     tail=new;                                                 //然後用新節點作尾巴
}
void initSnake()
{
     struct Snake *p;
     dir=RIGHT;
     while(head!=NULL)                                    //遍歷鏈表 把鏈表從頭到尾都復制給p並且一個個釋放掉 上一次遊戲撞牆死掉所使用的鏈表內存就清空了 head的初始值爲NULL
     {
          p=head;
          head=head->next;
          free(p);
     }                                                //該段用來釋放內存當蛇撞牆後重新定義蛇身的時候爲產生多餘的內存沒有釋放
     initFood();
     head=(struct Snake *)malloc(sizeof(struct Snake));
     head->hang=2;
     head->lie=2;
     head->next=NULL;
     tail=head;
     addNode();                                                //吃一個果實出一個尾巴
     addNode(); 
     addNode(); 
}
void deleNode()
{
     struct Snake *p;
     p=head;
     head=head->next;
     free(p);                                 //刪除鏈表頭後釋放該內存
}
int ifSnakeDie()
{
     struct Snake *p;
     p=head;
     if(tail->hang<0 || tail->lie==0 || tail->hang==20 || tail->lie==20 )
     {
          return 1;
     }
     while(p->next!=NULL)
     {
          if(p->hang==tail->hang && p->lie==tail->lie)
          {
               return 1;
          }
          p=p->next;
     }
     return 0;
}
void moveSnake()                              //移動的原理刪去鏈表頭 添加鏈表尾
{
     addNode();
     if(hasFood(tail->hang,tail->lie))
     {
          initFood();
     }
     else
     {
          deleNode();
     }
     if(ifSnakeDie())       //撞牆後重新開始 <0可以撞到上边界 碰到自己的身子
     {
          initSnake();
     }
}
void* refreshJieMian()
{
   while(1)
  {
    moveSnake();
    gamePic();       //刷新地圖
    refresh();       //刷新
    //sleep(1);      //秒
    //Sleep(1);       毫秒 不能用
    usleep(100000);    //1000000微秒 =1秒
  }
}
void turn(int direction)
{
     if(abs(dir)!=abs(direction))
     {
          dir=direction;
     }
}
void* changeDir()
{
   while(1)
   {
        key=getch();
        switch(key)
        {
             case KEY_DOWN:
                  turn(DOWN);
                  break;
             case KEY_UP:
                  turn(UP);
                  break;
             case KEY_RIGHT:
                  turn(RIGHT);
                  break;
             case KEY_LEFT:
                  turn(LEFT);
                  break;
        }
   }
}
int main()
{ 
  pthread_t t1;
  pthread_t t2;
  initNcurse();
  initSnake();
  gamePic();
  pthread_create(&t1,NULL,refreshJieMian,NULL);
  pthread_create(&t2,NULL,changeDir,NULL);
  while(1);
  getch();               //爲了看到程序結果 讓程序等待輸入
  endwin();              //回復終端
  return 0;


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值