-
C基础第三天
今天老师讲了数组和指针,单单是数组感觉难度不大,不难理解,但是和指针结合之后,对我来说难度就不止一点了,尤其是讲到最后,直接懵掉,感觉被绕晕了。老师先给我们讲解了昨天留的作业,又给我们出了几道题来巩固昨天的内容,然后才开始讲解数组和指针。
homework:猜拳小游戏
思路:
电脑: 石头(0) 剪刀(1) 布(2)
人: 石头(4) 剪刀(7) 布(10)
srand((unsigned)time(NULL))
a=rand()%3 0 1 2
人赢:5 || 9 || 10
电脑赢:6 || 7 || 11
else:平手
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
void main()
{
char people;
int computer,total;
while(1)
{
sleep(3);
system("clear");
printf("\n这是一个猜拳游戏:\n");
printf("A.石头\nB.剪刀\nC.布\nD.不玩了\n");
scanf("%c%*c",&people);
switch(people)
{
case 'A':
case 'a':
people=4;
break;
case 'B':
case 'b':
people=7;
break;
case 'C':
case 'c':
people=10;
break;
case 'D':
case 'd':
return;
default:
printf("输入有误,请重新输入");
}
srand((unsigned)time(NULL));
computer=rand()%3;// 0 1 2
switch(computer)
{
case 0:
printf("电脑出了:石头!\n");
break;
case 1:
printf("电脑出了:剪刀!\n");
break;
case 2:
printf("电脑出了:布!\n");
}
total=people+computer;
if(total==5 || total==9 || total==10)
{
printf("你赢了!\n");
}
else if(total==6 || total==7 || total==11)
{
printf("电脑赢了!\n");
}
else
{
printf("平手!\n");
}
}
}
练习:for 百钱买百鸡,公鸡 3/只 ,母鸡2/只 ,小鸡一块钱2只,问:实现一百块钱买一百只鸡。
思路:
公鸡:33
母鸡:50
小鸡:100-公-母
int g,m,x;
for(g=1;g<33;g++)
for(m=1;m<50;m++)
{
x=100-g-m;
if((g*3+m*2+x/2)==100 && x%2==0)
printf("%d %d %d\n",g,m,x);
}
数组:
定义数组: type typename[size];
例: int a[5]
定义了一个数组a,数组里面有5个元素,每个元素都是int 类型
访问数组中的每个元素:通过下标,
a[0]:第一个元素,
a[1]:第二个元素
....
a[n-1]; int a[n] ; 每个元素的下标号从0~n-1
特点:
1.各个元素在内存里面是紧紧相邻的。内存的最小单位是字节,一个字节一个地址。
- 能够通过下标号去快速访问数组里面的任何一个元素。
给数组赋值:
1.在定义的时候给它赋值(初始化)
例: int a[5]={1,2,3,4,5}
也可以不完全赋值
例: int a[5]={1,2,3} 这样,只会给数组里面的前3个元素赋值,后面没有赋到值的默认为0.
如果只定义了数组,但没有赋值,如果该数组是放在函数里面的,则该数组中的每个元素都是随机值。如果是放在函数外面的,则都是0。
int a[]={1,2,3,4,5}; 通过判断后面初始化元素的个数来确定数组的长度。
2.先定义,后赋值。
用过一个for循环来给一个数组赋值。
例: int a[n]
for(int i=0;i<n;i++)
a[i]=i;
注:1.对于数组,只能在定义它的时候通过初始化的方式整体访问它,其他任何时候都不能够整体访问一个数组,只能通过访问它的每一个元素去访问它。
2.在定义数组的时候,数组里面的元素的个数必须是个确定的值,不能是个变量。
练习:输出一个数组里面的最大值和最小值
#include <stdio.h>
void main()
{
int a[10];
for(int i=0;i<10;i++)
scanf("%d",&a[i]);
int max,min;
max=a[0];
min=a[0];
for(int i=1;i<10;i++)
{
if(max<a[i])
max=a[i];
if(min>a[i])
min=a[i];
}
printf("max:%d min:%d\n",max,min);
}
练习:输入10个数,保存在一个数组里,在数组中查找某个数,如果找到,就给出该数在数组中的位置,没有找到就输出“没有找到”。
#include <stdio.h>
void main()
{
int a[10],search,flag=0;
for(int i=0;i<10;i++)
scanf("%d",&a[i]);
printf("请输入要查找的值:");
scanf("%d",&search);
for(int i=0;i<10;i++)
{
if(search==a[i])
{
printf("找到了,位置是:%d\n",i+1);
flag++;
}
}
if(flag==0)
{
printf("没有找到!\n");
}
}
练习:定义一个6个长度的数组,里面有序排好了5个数(升序),现在插入一个数,使插入之后的数组依然有序(升序)。
#include <stdio.h>
void main()
{
int a[6],i,j,in;
//输入有序的5个数
for(i=0;i<5;i++)
scanf("%d",&a[i]);
printf("请输入要插入的数:");
scanf("%d",&in);
//确定插入的位置 =>i
for(i=0;i<5;i++)
if(a[i]>in)
break;
//把i后的数往后挪一个位置,空出i的位置
for(j=5;j>i;j--)
a[j]=a[j-1];
//插入in到i
a[i]=in;
//输出整个数组
for(i=0;i<6;i++)
printf("%d",a[i]);
printf("\n");
}
二维数组:
int a[2][3]
a[0][0] a[0][1] a[0][2]
a[1][0] a[1][1] a[1][2]
定义一个二维数组: int a[行数][列数]; 每一个元素的下标号分为行坐标和列坐标,都是从0开始递增,
赋值
1.在定义的时候赋值(初始化)
a. int a[2][3]={1,2,3,4,5};
b. int a[2][3]={{1,2},{3,4,5}};
2.先定义再赋值。
#include <stdio.h>
void main()
{
int a[2][3],i,j;
for(i=0;i<2;i++)
{
for(j=0;j<3;j++)
{
scanf("%d",&a[i][j]);
}
}
for(i=0;i<2;i++)
{
for(j=0;j<3;j++)
{
printf("%d",a[i][j]);
}
}
printf("\n");
}
练习:输入3行4列的整型矩阵,输出最大值和对应的下标号
#include <stdio.h>
void main()
{
int a[3][4]={{1,2,3,4},{5,6,12,8},{9,10,11,1}};
int c,r,i,j,max=a[0][0];
for(i=0;i<3;i++)
{
for(j=0;j<4;j++)
{
if(max<a[i][j])
{
max=a[i][j];
c=i;
r=j;
}
}
}
printf("%d %d %d\n",max,c,r);
}
基本数据:
常量
变量
数据的存在形式:%d %f %c
怎么操作基本数据:顺序结构 , 条件结构, 循环结构。
数组:
一维数组:
数据的存在形式: 基本数据
怎么去操作数组:基本数据的操作过程
=>
二维数组:
一维数组的另一种形式
int a=1;
基本数据与指针的关系、
#include <stdio.h>
void main()
{
int a=10;
*(&a)=20; //& :获取a的地址 *:表示该地址里面的值
printf("%d\n",a);
}
指针变量:定义一个变量用来接收一个地址。
例:定义一个变量,接收整型变量的地址
int a=10;
int *p=&a;
指针<=>地址
定义一个变量,接收字符型变量的地址
char c='a';
char *p=&c;
一维数组与指针的关系
1.要明白指针不仅要知道它的值,还要知道它指向的对象
2.数组名表示该数组首元素的首地址,指向的对象是数组里面的元素。
#include <stdio.h>
void main()
{
int a[7]={1,2,3,4,5,6,7};
printf("%p %p %p\n",a,&a[0],&a);
printf("%p %p %p\n",a+1,&a[0]+1,&a+1);
}
/*
a:表示数组的首元素的首地址,作为一个指针,指向的对象是数组里面的元素。+1,指针向后偏移一个所指对象的长度,一个元素,所以a+1,指向的是a[1].
&a:表示的是整个数组的地址,作为一个指针,指向的对象是整个数组.+1.指针向后偏移一个所指对象的长度,一个数组,所以,&a+1,指向数组结尾
*/
#include <stdio.h>
void main()
{
int a[5]={1,2,3,4,5};
// printf("%p %d\n",*(&a),**(&a));
// int *p//p是一个指针变量,接收一个int型数据的地址,作为一个指针,指向的对象是一个int型数据
int *p1=a;
int *p2=(int *)&a;
printf("%p %p\n",p1+1,p2+1);
}
// * :只有在定义一个变量的时候表示指针,其它任何时候都表示取地址里面的值。
下面的几个int定义只有写在代码框才能让星号正常显示
int p:定义了一个整型变量
int *p:定义了一个指向整型变量的指针,接收的是整型变量的地址
指针数组:指针的数组
int *p[5]:定义了一个含有5元素的数组,每个元素都是int *型,作为指针指向int 型的变量
数组指针:数组的指针
int (*p)[5]:定义了指针p。指向的是一个含有5个int型元素的数组
二维数组与指针的关系:
#include <stdio.h>
void main()
{
int a[4][5]={1,2,3,4,5,
6,7,8,9,10,
11,12,13,14,15,
16,17,18,19,20};
int (*p)[5]=a; //a作为指针指向数组的首元素的首地址,二维数组的元素是一维数组,所以,a指向第一行,停在第一行的第一个元素处,1的位置。
printf("a=%p a+1=%p\n",a,a+1); //a+1指向这个数组的第二行,指针停在6的位置
printf("*a=%p *(a+1)=%p\n",*a,*(a+1));//*a,作为一个指针,指向的是第一行里面的元素,停在1的位置,*a+1,作为指针,指向第一行的第二个元素,2, **a,就是取*a作为一个指针所指向的对象的值,即1.
printf("&(*a+1)=%p &(*a+1)+1=%p\n",&(*a),&(*a)+1);
printf("**(&(*a+1))=%d **(&(*a+1)+1)=%d\n",**(&(*a)),**(&(*a)+1));
printf("*a+1=%p *(a+1)+1=%p\n",*a+1,*(a+1)+1);
printf("**a=%d **(a+1)=%d\n",**a,**(a+1));
printf("*(*a+1)=%d *(*(a+1)+1)=%d\n",*(*a+1),*(*(a+1)+1));
printf("&a=%p &a+1=%p\n",&a,&a+1);
int (*p1)[3]=(int (*)[3])a;
printf("p1=%p p1+1=%p\n",p1,p1+1);
printf("**p1=%d **(p1+1)=%d\n",**p1,**(p1+1));
}
/*
1.一个指向行的指针前面加个*,就表示成指向列的指针。一个指向列的指针前面加个&就变成了指向行的指针。
2.二维数组是按行存储,先存第一行,然后依次存下一行,它的元素是行,每个元素在内存中相邻存放。
*/
函数
函数与指针的关系
字符串
上面三点估计是老师想讲但是没来得及讲的,毕竟数组和指针放一起还是有点搞头的,只能让我们消化一下等到明天再讲了。