C语言中sizeof以及多维数组的应用

C语言的指针和数组始终是我们的软肋,这里我也想记录下自己的学习情况。
首先说说sizeof的在指针里的用法:

array是数组指针,sizeof(array)返回指针指向的内存空间的长度 sizeof(int)是每个int类型占的内存空间 sizeof(array)/size(int)就是求出array里有多少个int类型数据,也就是数组的长度
这里附上一个C语言例程:
#include <stdio.h>

int main(void)
{
    int apricot[2][3][5]=
    {
        {
            {1,2,3,4,5},
            {6,5,4,3,2},
            {7,8,9,1,3}
        
        },
        {
            {2,3,4,5,6},
            {3,4,5,6,7},
            {4,5,6,7,8}            
        }

    };

    int (*p)[3][5] = apricot;
    int (*r)[5] = apricot[0];
    int *t = apricot[0][0];
    
    printf("The addr of apricot is 0x%0x\n", apricot);//数组首地址:0x22fedc
    printf("Size of the apricot in int= %d\n",(sizeof(apricot)/sizeof(int)));
    printf("Size of the apricot in byte = %d\n",(sizeof(apricot)));
    
    printf("The value of the apricot[0][0] = 0x%0x\n",apricot[0][0]);
    printf("The addr of the apricot[0][0] = 0x%0x\n",&(apricot[0][0]));
    printf("The value of the apricot[0] = 0x%0x\n",apricot[0]);
    printf("The addr of the apricot[0] = 0x%0x\n\n",&(apricot[0]));
    
    printf("The addr of r is   0x%0x\n", r);//打印r的地址
    printf("The value of *r is %d\n", (*r++)[0]);//打印之前r地址里的值,之后r++,指向有一个元素
    printf("The addr of r++ is 0x%0x\n", r);//打印r++之后的地址。
    printf("The value of *r++ is %d\n", (*r)[0]);//打印r++之后的地址里的值
    printf("The value of (*r)[1] is %d\n\n", (*r)[1]);//打印后一个元素的值
    
    printf("The addr of t is 0x%0x\n", t);//打印t的地址
    printf("The value of *t is %d\n", (*t++));
    /*打印之前t地址里的值,之后t++,指向有一个元素,此时t的地址为0x22fedc+4 = 0x22fee0*/
    printf("The addr of t++ is 0x%0x\n", t);//打印:0x22fee0
    printf("The value of *t++ is %d\n", (*t));//打印0x22fee0地址里的值
    printf("The value of (*++t) is %d\n\n", (*++t));//打印0x22fee0+4地址里的值
    
    printf("The addr of p is  0x%0x\n", p++);
    printf("The addr of *p is 0x%0x\n\n", *p);//其差值是60=15(3*5)*4
    

    return 0;
}
apricot是数组名,也是第一个元素的地址,sizeof(apricot)返回此地址以后的指向的内存空间的长度
以下是我在windows下用gcc编译运行的结果:
Size of the apricot in int= 30
Size of the apricot in byte = 120
The value of the apricot[0][0] = 0x22fedc
The addr of the apricot[0][0] = 0x22fedc
The value of the apricot[0] = 0x22fedc
The addr of the apricot[0] = 0x22fedc

The addr of r is 0x22fedc
The value of *r is 1
The addr of r++ is 0x22fef0
The value of *r++ is 6
The value of (*r)[1] is 5

The addr of t is 0x22fedc
The value of *t is 1
The addr of t++ is 0x22fee0
The value of *t++ is 2
The value of (*++t) is 3

The addr of p is 0x22fedc
The addr of *p is 0x22ff18

sizeof(int)是每个int类型占的内存空间,在x86里占4个字节。
在本例程中,共有2*3*5个数组元素,30个int元素。如果用字节显示的话,就是4*30=120个字节,

The addr of r is   0x22fedc
The addr of r++ is 0x22fef0
这两个执行结果的意思就是:
r指向的是数组的首地址:0x22fedc,但是r++后的值f0-dc=14(hex)= 20(D),就是5*4(int)= 20个字节,说明r本身是一个指针,指向的是一个包含5个元素的数组。
(*r)[5] = apricot[0];这句话的意思就是把apricot[0]的地址赋给指针r

*t = apricot[0][0];意在把apricot[0][0]的地址值赋给指针t
The addr of t is   0x22fedc
The addr of t++ is 0x22fee0
t本身是一个指针,它指向apricot[0][0]内存所存储的数组内容,t自增1就是t的值+4(int),于是t就指向下一个元素。这也就是

The value of *t++ is 2
The value of (*++t) is 3

所表达的意义。

还有一点apricot[0]和apricot[0][0]是一个常量,自增或自减都是非法的,(也就是说,指针是可以自增自减的,而数组名是个常量,不可以改变的。)

编译会有这样的而结果:

TriArray.c:30: error: lvalue required as increment operand

有啥说的不妥的地方欢迎指正!!~~~谢谢!(*^__^*)



原文地址:https://www.cnblogs.com/CodeWorkerLiMing/p/2458950.html