菜鸟笔记
提升您的技术认知

C语言有关数组的运算

在开始之前,我们先来复习一下基础知识:
  • sizeof是一个单目运算符,计算数据类型或变量长度(包括‘\0’);
  • strlen(地址),以’\0’为结束标志计算字符串长度的函数(不包括’\0’);
  • &+数组名,数组名表示整个数组,这里取出的是整个数组的地址 ;
  • sizeof(数组名),数组名表示整个数组,计算的是整个数组的大小,单位是字节
  • 除了以上两种形式表示整个数组之外,其余情况当遇到数组名时均表示数组首元素的大小!
    下面我们来一起看一些常用的例子吧!
一、一维数组
int main()
{
    int a[] = { 1, 2, 3, 4 };
    printf("%d\n", sizeof(a));//16-->sizeof(a)表示整个数组,计算整个数组大小,单位字节,这里a是整型数组,有四个元素,因此是16
    printf("%d\n", sizeof(a + 0));//4-->a+0表示数组首元素的地址,即“1”的地址
    printf("%d\n", sizeof(*a));//4-->a代表数组首元素的大小,对a解引用,就是首元素的大小
    printf("%d\n", sizeof(a + 1));//4-->类似于上述的a+0,这里代表的是“2”的地址
    printf("%d\n", sizeof(a[1]));//4-->相当于上述的a+1,代表的是“2”的地址
    printf("%d\n", sizeof(&a));//4-->&a表示整个数组的地址,在32位平台下,一个地址的大小为4
    printf("%d\n", sizeof(*&a));//16-->&a表示整个数组的地址,解引用表示整个数组的大小
    printf("%d\n", sizeof(&a + 1));//4-->&a表示整个数组,再加一表示跳过整个数组后的下一个元素地址,虽然不存在,求地址仍然是合法的,访问就不合法了
    printf("%d\n", sizeof(&a[0]));//4-->首元素的地址
    printf("%d\n", sizeof(&a[0] + 1));//4-->首元素地址加一,即就是第二个元素“2”的地址

    return 0;
}

运行结果:

二、字符数组
  • 1.
int main()
{
    char arr[] = { 'a', 'b', 'c', 'd', 'e', 'f' };
    printf("%d\n", sizeof(arr));//6-->arr表示整个数组的大小
    printf("%d\n", sizeof(arr + 0));//4-->数组首元素的地址
    printf("%d\n", sizeof(*arr));//1-->数组首元素的大小
    printf("%d\n", sizeof(arr[1]));//1-->数组第二个元素的大小
    printf("%d\n", sizeof(&arr));//4-->数组的地址
    printf("%d\n", sizeof(&arr + 1));//4-->整个数组加一,和上面原理相同
    printf("%d\n", sizeof(&arr[0] + 1));//4-->第二个元素的地址

    printf("%d\n", strlen(arr));//随机值-->arr表示首元素地址,但数组arr中没有'\0'结束标志,当strlen()函数从'a'数到'f'的时候会一直往后数
    printf("%d\n", strlen(arr + 0));//随机值-->表示的仍然是首元素的地址,道理和上面的这个类似
    //printf("%d\n", strlen(*arr));//错误-->*arr代表数组首元素的大小,但是strlen求的是参数的地址
    //printf("%d\n", strlen(arr[1]));//错误-->arr[1]代表字符'b',访问strlen('b')是无效的
    printf("%d\n", strlen(&arr));//随机值-->表示数组的地址
    printf("%d\n", strlen(&arr + 1));//随机值-->跳过整个数组的地址的一个随机值(和strlen(arr)相差6)
    printf("%d\n", strlen(&arr[0] + 1));//随机值-->数组第二个元素的一个随机值(和strlen(arr)相差1)

    return 0;
}

运行结果:出现报错

  • 2.
int main()
{
    char arr[] = "abcdef";
    printf("%d\n", sizeof(arr));//7---arr表示整个数组
    printf("%d\n", sizeof(arr + 0));//4---数组首元素地址
    printf("%d\n", sizeof(*arr));//1---数组首元素
    printf("%d\n", sizeof(arr[1]));//1---数组首元素
    printf("%d\n", sizeof(&arr));//4---数组的地址
    printf("%d\n", sizeof(&arr + 1));//4----数组的地址加1,跳过整个数组的地址
    printf("%d\n", sizeof(&arr[0] + 1));//4---首元素的地址加+1,即第二个元素的地址

    printf("%d\n", strlen(arr));//6---arr表示数组首元素地址
    printf("%d\n", strlen(arr + 0));//6---arr+0表示数组首元素地址
    //printf("%d\n", strlen(*arr));//错误代码
    //printf("%d\n", strlen(arr[1]));//错误代码
    printf("%d\n", strlen(&arr));//6---表示数组的地址,但在值上和首元素地址一样
    printf("%d\n", strlen(&arr + 1));//随机值---数组的地址加1,跳过整个数组的地址
    printf("%d\n", strlen(&arr[0] + 1));//5---&arr[0]首元素的地址加+1,即第二个元素的地址

    return 0;
}

运行结果:

  • 3.
int main()
{
    char *p = "abcdef";
    printf("%d\n", sizeof(p));//4-->P是指针变量的值,指针变量就是地址,保存“a”的地址
    printf("%d\n", sizeof(p + 1));//4-->表示“b”的地址
    printf("%d\n", sizeof(*p));//1-->p指向首元素的地址,解引用后表示“a”的大小
    printf("%d\n", sizeof(p[0]));//1-->表示字符串第一个元素的大小
    printf("%d\n", sizeof(&p));//4-->指针变量的地址
    printf("%d\n", sizeof(&p + 1));//4-->跳过一个指针地址的大小的地址
    printf("%d\n", sizeof(&p[0] + 1));//4-->表示第二个元素的地址

    printf("%d\n", strlen(p));//6-->p指向字符串首元素地址,即计算整个字符串长度(不包括'\0')
    printf("%d\n", strlen(p + 1));//5-->字符串首元素的地址加+1,即第二个元素的地址,即计算从第二个字符开始的字符串长度
    //printf("%d\n", strlen(*p));//错误-->strlen函数里面存放的是地址!!!
    //printf("%d\n", strlen(p[0]));//错误-->strlen函数里面存放的是地址!!!
    printf("%d\n", strlen(&p));//随机值-->&p代表取字符a的地址的地址,不知道\0的位置
    printf("%d\n", strlen(&p + 1));//随机值-->&p代表取字符a的地址的地址,不知道\0的位置
    printf("%d\n", strlen(&p[0] + 1));//5-->从字符b开始统计,遇到f后面的\0停止

    return 0;
}

运行结果:

三、二维数组
int main()
{
    int a[3][4] = { 0 };
    printf("%d\n", sizeof(a));//48-->sizeof(数组名),代表整个数组大小
    printf("%d\n", sizeof(a[0][0]));//4-->第一行第一个元素的大小,4个字节
    printf("%d\n", sizeof(a[0]));//16-->第一行元素的大小4*4
    printf("%d\n", sizeof(a[0] + 1));//4-->第一行第二个元素的大小
    printf("%d\n", sizeof(a + 1));//4-->第二行第一个元素的地址
    printf("%d\n", sizeof(&a[0] + 1));//4-->第二行的地址
    printf("%d\n", sizeof(*a));//16-->第一行元素的大小4*4
    printf("%d\n", sizeof(a[3]));//16--> sizeof内部的表达式不参与运算,a[3]代表数组第四行的元素的大小,4*4=16个字节,虽然没有第四行,求大小可以,访问不行
    //在对数组进行运算时,对指针解引用,取决于指针的类型

    return 0;
}