二维数组、可变长数组、多维数组、函数调用

1.二维数组名称也可以代表数组里第一个存储区的地址。

例子:

 输出结果:二维数组的名称=二维数组第一个数的地址

 二维数组的名称也不可以被赋值。

二维数组名称也可以进行sizeof计算,结果是二维数组里所有存储区的总大小。

例子:

输出结果:这个数组有6个存储区,一个存储区占4字节,所以这个数组的大小就是24字节

 二维数组名称后可以只使用一个下标,这个下标当做组下标使用。

这个写法可以表示下标对应组里第一个存储区的地址。

例子:

输出结果:arr[1]==&arr[1][0]

这个写法也可以当作一维数组使用,这个一维数组里包含下标对应组里所有的存储区。

例子:

 输出结果:arr[1]相当于包含两个存储区,一个存储区4字节,所以有8字节。

 练习:先把下面的数存进二维数组,然后用二维数组把下面的数打印出来

#include <stdio.h>
int main(){
   int array[5][5]={0};
   int i=0,j=0;
   for(i=0;i<5;i++){
       for(j=0;j<5;j++){
          if(j==2){
              array[i][j]=1;
          } else if(i==2){
              array[i][j]=2;
          }
          else if(j==i){
              array[i][j]=3;
          } else if(j+i==4){
              array[i][j]=4;
          }
       }
   }
   array[2][2]=0;
   for(int a=0;a<5;a++){
       for(int b=0;b<5;b++){
           printf("%d ",array[a][b]);
       }
       printf("\n");
   }
    return 0;
}

输出结果:

 练习:扫雷:写出10行O,其中有10个X,每次运行X的位置不固定

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(){
    srand(time(0));
    int sub=0,sup=0;
    int ans=0;
   char array[10][10]={0};
  do{
      sub = rand()%10;  //rand()%10取的是0~9的随机数
      sup = rand()%10;
     //因为rand()%10是随机数,要保证有10个不重复的地雷
     //先随机数组里的数,是否为1,是1就是地雷,判断是否是地雷,如果不是地雷就插入数子1,为地雷
      if(!(array[sup][sub]&15)){ //15的二进制是 0000 1111 (0与15做按位与结果一定是0,就不是地雷)
          array[sup][sub] |= 15; //与15做按位或,0和15做按位与结果都是1,就插入1,为地雷
          ans++;
      }
  }while(ans<10);//向全是0的数组array里随机抽10个数变成1
   for(sup=0;sup<10;sup++){
       for(sub=0;sub<10;sub++){
          if(array[sup][sub]&15==15){
              printf("X");
          }
          else if(!(array[sup][sub]&15)){
              printf("0");
          }
       }
       printf("\n");
   }
    return 0;
}

输出结果:

扫雷进阶版提示附近地雷数量:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(){
    srand(time(0));
    int sub=0,sup=0,ans=0;
    int trow=0,tcol=0;
   char array[10][10]={0};
   int delta[][2]={-1,-1,-1,0,
                   -1,1,0,-1,
                   0,1,1,-1,
                   1,0,1,1};
  do{
      sub = rand()%10;
      sup = rand()%10;
      if(!(array[sup][sub]&15)){
          array[sup][sub] |= 15;
          ans++;
      }
  }while(ans<10);

  for(sup=0;sup<10;sup++){
      for(sub=0;sub<10;sub++){
          if((array[sup][sub]&15)!=15){ //判断是否为地雷,与15做按位与!=15就不是地雷
              continue;
          }
          for(int num=0;num<8;num++){
              trow = sup + delta[num][0];
              tcol = sub + delta[num][1];
              if(trow<0 || trow>9){
                  continue;
              }
              if(tcol<0 ||tcol>9){
                  continue;
              }
              if((array[trow][tcol] & 15) == 15){//判断是否为地雷,与15做按位与==15就是地雷

                  continue;
              }
              array[trow][tcol]++;
          }
      }
  }

   for(sup=0;sup<10;sup++){
       for(sub=0;sub<10;sub++){
          if((array[sup][sub]&15)==15){
              printf("X");
          }
          else if(!(array[sup][sub]&15)){
              printf("0");
          }
          else{
              printf("%d",array[sup][sub] & 15);
          }
       }
       printf("\n");
   }
    return 0;
}

输出结果:

 2.C语言里允许采用分组的方式管理程序里的语句。

每个语句分组叫做一个函数。

多函数程序执行时,时间分配情况必须遵守以下规则:

(1)这个程序的执行时间被分成几段,不同时间段被分配给不同的函数使用。

(2)任何两个时间段不能互相重叠并且所有时间段必须连续。

(3)如果函数A把自己的时间分配给函数B使用,则函数B完成所有工作之后必须把后面的时间还给函数A。

可以的:

 

 不可以的:

 如果函数A把自己的时间分配给函数B使用,则它们之间存在函数调用关系。

在这个调用关系中函数A叫做调用函数,函数B叫做被调用函数。

只有被调用函数工作期间函数调用关系才存在。

 调用函数里编写调用语句会在函数间产生函数调用关系。

函数调用例子:

 输出结果:

不可以跨函数使用变量。 

例子:

运行结果:

 不同函数里的变量可以重名。

例子:

运行结果:

如果函数多次执行,则每次执行的时候函数里面的变量对应的存储区都可能不同。

 例子:

 

3.使用volatile关键字声明的变量,对应的存储区内容可以被其它程序修改。 

4.函数调用过程中,通常伴随着两个函数之间数据的传递。

数据传递存在两个完全相反的方向,既可以从调用函数向被调用函数传递,也可以从被调用函数向调用函数传递。

无论哪个方向的数据传递都需要使用被调函数提供的存储区。

只能从被调函数向调用函数传递一个数据。

这个数据叫做被调用函数的返回值。

 只能在被调用函数结束的时候才能向调用函数传递返回值。

返回值必须存放在被调用函数提供的一个存储区里,这个存储区的类型名称应该写在被调用函数名称前面。

被调用函数里使用return关键字把返回值记录到存储区里。

调用函数里把函数调用语句当作数字使用,就可以获得被调用函数的返回值。

例子:

运行结果:

练习:

#include <stdio.h>
int add(void){
    int num1=0,num2=0;
    printf("请输入两个整数:");
    scanf("%d%d",&num1,&num2);
    return num1+num2;

}
int main(){
    int num=add();
    printf("求和结果为%d",num);
    return 0;
}

输出结果:

 如果被调用函数没有使用return关键字设置返回值,则函数返回值是随机的。

 调用函数只有一次获得返回值的机会,得到以后或者立即使用或者存储到某个存储区里。

如果函数名称前写void表示函数不提供存放返回值的存储区。 

如果函数名称前什么都不写,在C99规范里表示函数提供一个整数类型存储区,用来存放返回值,C99里不允许这样。

被调用函数不可以使用数组记录返回值。

可以从调用函数向被调函数传递多个数据,这些数据的类型可以不同。

被调函数需要为每一个数据提供一个对应的存储区。

需要在函数名称后面的小括号里声明一组变量,用它们表示前面提到的存储区。

这些变量叫做函数的形式参数,小括号里的所有内容叫做函数的形式参数列表。

每个形式参数的类型名称都不可以省略。

相邻的形式参数声明之间用逗号分开。

被调用函数里可以像使用变量一样使用这些形式参数。

调用带参数的函数时需要在函数调用语句的小括号里为每一个形式参数提供一个对应的数字。

计算机吧这些数字记录在对应的形式参数里,被调用函数可以通过形式参数得到这些数字。

这些数字叫做实际参数

只要能当作数字使用的内容都可以作为实际参数使用。

如果一个函数不提供形式参数就应该在函数名称后的小括号里写void。

如果函数名称后面的小括号里什么都没有写,表示函数可以提供任意多个不确定类型的形式参数。

例子:

 输出结果:

 练习:鸡兔同笼问题

#include <stdio.h>
int add(int heads,int legs){
    int rabbit=0;
    for(int rabbit=0;rabbit<heads;rabbit++){
       if( 4*rabbit+2*(heads-rabbit)==legs){
           return rabbit;
       }
    }
}
int main(){
    int heads=0,legs=0;
    printf("请输入头和脚的数量:");
    scanf("%d%d",&heads,&legs);
    int num=add(heads,legs);
    printf("兔子的数量为%d只,鸡的数量为%d只\n",num,heads-num);
    return 0;
}

运行结果:

 

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

lune_one

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值