黑马程序员——C语言笔记之数组

------- android培训java培训iOS培训.Net培训、期待与您交流! ----------

一、数组的概念

1、数组的定义:把具有相同类型若干变量有序的形式组织,这些按序排列的同类数据元素的集合称为数组。

一个数组可以分解为多个数组元素,这些数组元素可以是基本数据类型或是构造类型。(数组属于构造数据类型)

2、数组元素:构成数组的数据

     数组的下标:是数组元素的位置的一个索引或指示

     数组的维度:数组元素下标的个数

3、按存储内容分类:数值数组、字符数组、指针数组、结构数组。

4、按维度分类:一维数组、二维数组、多维数组。

二、一维数组

1、概念:如果一个数组的元素不是数组,那么就是一维数组。

2、一维数组的定义:类型说明符 数组名[常量表达式];

3、数组定义的注意点:

1) 数组的类型实际上是指数组元素的取值类型。对于同一个数组,其所有元素的数据类型都是相同的。第一个数组元素的地址是数组所占内存块的首地址。

2)数组名的书写规则应符合标识符的书写规定。 

命名规则:

(1)只能由字母、数字、下划线组成

(2)不能数字开头

(3)不能与关键字重名

(4)严格区分大小写

命名规范:

(1)起一个有意义名字

(2)驼峰标示

(3)数组名不能与其它变量名相同。

(4)方括号中常量表达式表示数组元素的个数,如a[5]表示数组a有5个元素。但是其下标从0开始 计算。因此5个元素分别为a[0], a[1], a[2], a[3], a[4]。

(5)不能在方括号中用变量来表示元素的个数,但是可以是符号常数或常量表达式。c99不支持使用变量作为元素个数,但llVM编译器,它支持

(6)允许在同一个类型说明中,说明多个数组和多个变量。

初始化:

#include <stdio.h>

int main(int argc, const char * argv[]) {
   
    //1、定义的同时进行初始化
    
    int a[5]={1,23,3,4,45};  //完全初始化
    
    int a1[]={1,2,3};   // 长度是3
    
    //2、定义的同时,部分初始化
    
    int a2[4] = {1};   //1 赋值给数组的第一个元素  a2[0]
    
    int a3[5] = {[2]=3,[4]=100};//  指定元素初始化

    //3、先定义后初始化
    int a4[3];   // 长度是 3   下标:0~2
    a4[0]  = 1;  //a4第一个元素
    a4[1]  = 10;
    a4[2]  = 100;//a4最后一个元素
    
//    int len = 4;
//    int a5[len]={1,2,3,4};  //错误的
    
    return 0;
}

数组在初始化之前和之后元素的值

(1)如果定义数组后没有初始化数组中是有值的是随机的垃圾数,所以如果想要正确使用数组应该要进行初始化。

(2)对于数组来说,一旦有元素被初始化,其他元素都被赋值0。

数组的存储方式

(1)计算机会给数组分配一块连续的存储空间

(2)数组名代表数组的首地址,从首地址位置,依次存入数组的第1个、第2个....、第n个元素

(3)每个元素占用相同的字节数(取决于数组类型)

(4)并且数组中元素之间的地址是连续。 

数组的长度

数组的长度=数组占用的总字节数/数组元素占用的字节数

int len = sizeof(数组名) / sizeof(数组类型);

数组的越界:轻则导致原有数据被覆盖,重则导致系统奔溃。

数组的小练习:彩票开奖

#include <stdio.h>
#include <stdlib.h>
void caipiao(){

    //先产生一注
    //一注有5个数
    int num[5],j;
    
    for (int k=0; k<5; k++) {
        for (int i=0; i<5; i++) {
            //只产生一个随机数
            int r = arc4random_uniform(21)+1;
            //把产生的每一个数都存放到数组中
            num[i]=r;
            
            for (j=0; j<i; j++) {   
                //找到重复的数了,直接退出里层的循环了
                if (num[j]==r) {
                    //printf("有重复\n");
                    break;
                }
            }
            //j == i 表示新产生的数和以前产生的数都已经比较一遍了
            //没有找到重复的
            if(j==i){
                
                printf("%d\t",r);
                
            }else{
                
                i--; //再产生一个随机数
            } 
        }
        //5个数不能重复
        printf("\n");  
    } 
}
int main(int argc, const char * argv[]) {

    caipiao();
    
    return 0;
}
数组元素作为函数的形参与普通变量用法一致,是“值传递”

当数组名作函数参数时实参与形参之间不是值传递”,而是“地址传递”,实参数组名将该数组的起始地址传递给形参数组两个数组共享一段内存单元编译系统不再为形参数组分配存储单元。 

冒泡排序的代码如下:

#include <stdio.h>
void maopao(int a[],int len){

    for(int i=0;i<len-1;i++){ 
        //len - i 因为没一趟 都能能确定一个最大的数
        //第i趟,可以确定i个最大的数
        
        for (int j=0; j<len-i-1; j++) {
              //相邻的两个数进行比较
            if (a[j]>a[j+1]) {
                
                //交换a[j] 和 a[j+1]的值
                int temp;
                temp = a[j];
                a[j] = a[j+1];
                a[j+1] = temp;      
            }       
        } 
    }
}

void print_arr(int a[],int len){

    for (int i=0; i<len; i++) {
        printf("%d\t",a[i]);
    }
    printf("\n");
}

int main(int argc, const char * argv[]) {
    int  a[5]={12,3,45,88,10};
    print_arr(a, 5);//将数组名作为函数参数
    //进行冒泡排序
    maopao(a, 5);
    print_arr(a, 5);

    return 0;
}

三、二维数组

1、定义:一维数组的每一个元素又是一个一维数组(嵌套)为二维数组

类型说明符 数组名[常量表达式1][常量表达式2]

2、初始化

//1.定义的同时初始化
int a1[3][2]={1,2,3,4,5,6};
int a2[3][2]={{1,2},{3,4},{5,6}};
int a5[3][3]={{1},{2},{3}};//相当于下面的数字矩阵 
int a7[3][3]={{[1]=34},{[0]=10},{[2]=29}};
int a8[3][3]={[2][2]=12};
int a8[][2]={1,2,3,4,5,6};//二维数组支持定义的时候,不指定第一维长度 
//2.先定义后初始化
int a10[2][2]; 
a10[0][0]= 133; 
a10[1][0]= 12;
3、存储细节

int a[2][2];

数组的首地址 = a = a[0] = &a[0][0]

二维数组的占用的总字节数:2*2*4 = 16

                                            sizeof(a) = 16

二维数组的行数:sizeof(a)/sizeof(a[1])

                  列数:sizeof(a[0])/sizeof(int) 

应用:求多门功课的平均成绩

#include <stdio.h>

int main(int argc, const char * argv[]) {
    //一个学习小组有5个人,每个人有三门课的考试成绩。每门课程的平均分和三门课的平均分。
    int score[5][3]={
        {80,75,92},
        {61,65,71},
        {59,63,70},
        {85,87,90},
        {76,77,85} 
    };

    int sum;
    float total=0.0f; //存储总平均分
    //遍历
    for (int i=0; i<3; i++) {
        //每统计一门课的成绩和之后,统计下一门课之前要清0
        sum = 0;
  
        for (int j=0; j<5; j++) {
            
            //a[j][i] 取出每一列的值
            sum += score[j][i];
            
        }
        //(sum / 5.0f)每一门课的平均分
        printf("第%d门课的平均分:%.2f\n",i+1,sum/5.0f);
        total += (sum / 5.0f);
    }
    //总平均分
    printf("总平均分:%.2f\n",total/3);
    return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值