数组分为一维,二维,多维。

一维数组:
#define M 5
int main() {
    //数组:一组相同数据类型的结合
    //数组的定义:  type_t  arr_name [const_n]
    //[const_n] 里面是数组长度,只能是常量表达式来指定数组的大小
    //const 不可以当做常量给数组长度,const修饰的常量本质上是一个变量
//#define 宏定义可以当做数组长度
    int arr1[M] = { 1, 2, 3, 4, 5 };
    //数组的初始化:数组初始化就是在数组的定义时就给它赋好值
    int arr2[3] = { 1,2,3 }; // 完全初始化
    int arr3[5] = { 1, 2 }; // 不完全初始化  指定了数组长度是5,后面的都是0 
    int arr4[] = { 10, 20, 30, 40 }; // 这种没有指定数组长度的,它会根据它里面元素默认加上。效果跟arr1一样

    char str1[] = { 'a','b','c' }; //  内容就是 'a' 'b' 'c' 
    char str2[5] = { 'a', 'b', 'c' }; // 后面两个给 0 或者是 '\0' 填满,因为0的ASCll值是'\0'
    char str3[] = { "abc" }; // 默认后面会加上一个'\0' 它是字符串的结束标志
    char str4[5] = { "abc" }; // 长度未满用0 || '\0' 补满

    printf("%d\n", strlen(str1)); // 注意这个字符的长度是随机值,因为它不知道什么时候会碰到 '\0' ,碰到'\0' 才算结束
    printf("%d\n", strlen(str2)); // 这个我们长度给了5 ,里面的内容不足5个,用'\0' 补,它的第三个后就是 '\0',所有是3
    printf("%d\n", strlen(str4));

    //如果拿到数组里面的数据:通过一个操作符:[] 下标引用操作符通过循环来拿到它里面的数据,小标从0 开始。其实它就是数组访问的操作,
    printf("%c\n", str1[0]); 
    //数组的大小可以通过计算得到:strlen(arr) / strlen(arr[0])

    //一维数据在内存中的储存
    int    demo[10] = { 1,2,3,4 };
    int i = 0;
    for (i = 0; i < 10; i++) {
        printf("%p\n", &demo[i]);
        /*仔细观察输出的结果,我们知道,随着数组下标的增长,元素的地址,也在有规律的递增。
            由此可以得出结论:数组在内存中是连续存放的*/
    }
    //数组名是数组的首元素地址 我们知道了数组首元素地址就可以知道它后面的元素
    printf("%d\n", *demo); // 得到第一个元素的地址
    int* p = demo; //  既然数组名是数组的首元素地址,把首元素地址给p
    
    for (int i = 0; i < 10; i++) {
        printf("%d ", *p);
        p++; // p++ 指向后面的地址,我们就可以通过它的首元素地址,拿到整个数组元素
    }
    return 0;
}

只有字符数组里面有'0' 整型数组是没有'0'的。

二维数组:
int main() {
    //二维数组
    //二维数组的创建:
    //第一个[]里面存的是行,第二个[]里面存的是列,表示这是一个几行几列的数组
    int arr1[2][4] = { 1, 2, 3, 4, 5, 6, 7, 8 };// 完全初始化
    int arr2[3][4] = { 1, 2, 3, 4,5,6,7,8 }; // 不完全初始化,没满数组个数用 0补
    int arr3[][4] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; // 行数可以省略,列数不可以!它会根据里面的元素,生成行
    int arr4[4][3] = { {1,2,},{4,5,6}, {7,8,9} };//一个{} 表示一个行数,里面的内容表示列的内容,同样的长度不够用 0 补
    //访问二维数组 用下标
    printf("%d\n", arr4[0][0]); // 行和列的第一个元素都是从0开始 
    printf("%d\n", arr4[1][0]);// 访问第二行的第一列的元素
    
    int i = 0;
    int j = 0;
    for (i = 0; i < 4; i++) {
        for (j = 0; j < 3; j++) {
            printf("arr4[%d][%d]=%d ", i,j,arr4[i][j]); // 知道arr4的元素内容
        }
        printf("\n");
    }

    //二维数组在内存中的存储
    //int a = 0;
    //int b = 0;
    for (i = 0; i < 4; i++) {
        for (j = 0; j < 3; j++) {
            printf("arr4[%d][%d]=%p ", i, j, &arr4[i][j]); // 二维数据在内存中的存储也是连续的
        }
        printf("\n");
    }
    
    int* p = arr4;
    int n = 0;
    for (n = 0; n < 12; n++) {
        printf("%d   ", *p); //既然二维的数组的内存存储也是连续的那么我们通过这种方式得到它的全部元素
        p++;
    }

    //数组作为函数参数
    printf("-------------------\n");
    int sortData[] = { 10,9,8,7,6,5,4,3,2,1,0};
    int sz = sizeof(sortData) / sizeof(sortData[0]) - 1;
    Sort(sortData,sz);
    
      数组作为函数传参的时候,有两种形式:
    1.数组形式
    2.指针形式
    注意:它们的本质上传的都是指针
    
    //数组名是什么? 
    //数组名是数组首元素地址
    //但是有两种例外:1.sizeof(arr) [在sizeof()里面的数组名不是数组元素首地址,而是整个数组] 2. &数组名,取出的是整个数组,这里的数组名表示的是整个数组
    int demo1[] = { 1, 2, 3 };
    printf("\n%p\n", demo1);
    printf("%p\n", &demo1);
    // 打印上面两个会发现地址是一样的。这里它们的意思不是一样的。
    printf("--------------\n");
    //demo1++;
    int* p1 = demo1;
    printf("%p\n", p1);
    p1++;
    printf("%p\n", p1);
    printf("%d\n", *p1);
    return 0;
}
文章目录