C语言学习记录——삼십일 指针数组题(1)

目录

练习

一维数组

1、整形数组

2、字符数组

现在换一下,把sizeof换成strlen

3、常量字符串

现在换成strlen

如果换成*p,sizeof

换成strlen


练习

一维数组

1、整形数组

int main()
{
    int a[] = { 1, 2, 3, 4 };    
    printf("%d\n", sizeof(a));    16
    sizeof(a + 0);    4
    sizeof(*a);   4
    sizeof(a + 1);   4
    sizeof(a[1]);  4
    sizeof(&a);  4
    sizeof(*&a);   16
    sizeof(&a + 1);     4
    sizeof(&a[0]);    4
    sizeof(&a[0] + 1);    4
    return 0;
}

11、int类型的数组,4个元素,每个元素大小是4个字节。sizeof (数组名),计算的是整个数组总大小,单位是字节,16个字节。

22、对于数组名的使用:

sizeof(数组名)

&数组名

只有这两个数组名代表整个数组,其他都是首元素地址。所以是4/8个字节。

33、对a解引用,拿到的是首元素地址,所以是4

44、a + 1,也就是第二个元素,所以还是4/8个字节

55、a[1]不必多写

66、&a, 取出的是数组的地址,地址大小就是4/8个字节,看平台。

77、*&a。拿出a的地址,然后解引用,其实也就是求整个数组的大小,和第一个一样,16

88、&a + 1,数组的地址+1,也就是从起始位置越过一整个数组,但实际上还是个地址,所以就是4/8个字节。

剩下两个,取出第一个元素的地址,和+1,都一样,4/8。

2、字符数组

int main()
{
    char arr[] = {'a', 'b', 'c', 'd', 'e', 'f'}; 
    printf("%d\n", sizeof(arr));   6
    sizeof(arr + 0);   4
    sizeof(*arr);   1
    sizeof(arr[1]);   1
    sizeof(&arr);   4
    sizeof(&arr + 1);   4
    sizeof(&arr[0] + 1);   4
    return 0;
}

参考上面即可。

现在换一下,把sizeof换成strlen

int main()
{
    char arr[] = {'a', 'b', 'c', 'd', 'e', 'f'};
    printf("%d\n", strlen(arr));
    strlen(arr + 0);
    strlen(*arr);
    strlen(arr[1]);
    strlen(&arr);
    strlen(&arr + 1);
    strlen(&arr[0] + 1);
    return 0;
}

11、随机值。strlen需要找到\0才会停止,所以求出的字符串长度也就是随机值。strlen(arr),arr表示的是首元素地址,从头开始往后找0。

22、+0还是一样,所以还是首元素地址。

33、非法访问地址。strlen需要的是一个地址,而*arr是解引用首元素地址,得到首元素,也就是'a'。a的ANSCII码值是97,也就是strlen会把97当作一个地址,往后访问,也就造成了非法访问地址。这样的代码不可写,程序会崩溃,访问97在内存中的地址时会发生访问冲突。

44、把'b'传了过去。也是崩溃

剩下三个,&arr也就是首元素地址,还是随机值。&arr + 1,从'f'之后开始找0,也是随机值,不过能知道的是,这两个差值是整个字符数组。&arr[0] + 1,是从'a'开始的,&arr是从'a'之前开始的,所以也能知道随机值之间的差值。

3、常量字符串

int main()
{
    char arr[] = "abcdef";  
    printf("%d\n", sizeof(arr));    7
    sizeof(arr + 0);   4/8
    sizeof(*arr);    1
    sizeof(arr[1]);  1
    sizeof(&arr);  4
    sizeof(&arr + 1);    4
    sizeof(&arr[0] + 1);    4
    return 0;
}

11、arr里面放着一个字符串,sizeof读取,知道\0为止,所以为7

22、arr在里面是首元素地址,所以还是地址的大小,4/8

33、*arr,arr首元素地址,解引用后找到首元素,就是1了

44、arr[1]

55、&arr,是地址,所以4/8

66、&arr + 1,一样,还是地址,所以4/8

77、&arr[0] + 1,指向的是b,还是地址。4/8

现在换成strlen

int main()
{
    char arr[] = "abcdef";
    printf("%d\n", strlen(arr));     6
    strlen(arr + 0);   6
    strlen(*arr);   err
    strlen(arr[1]);    err
    strlen(&arr);     6
    strlen(&arr + 1);    随机值
    strlen(&arr[0] + 1);   5
    return 0;
}

33、*arr 是首元素a的地址,所以97还是被strlen当成了地址,所以越界访问

44、一样,第二个元素

55、&arr,数组的地址。如果把他放到一个数组指针,那就是char (*p) [7] = &arr。所以类型就是char (*) [7]。但是这个strlen函数的类型不同,不兼容,所以会有警告。不过强行这么也可以,把&arr就当成一个地址看。所以是6。

66、&arr + 1,随机值

77、 &arr[0] + 1,从b开始数,所以是5。

如果换成*p,sizeof

int main()
{
    const char *p = "abcdef";
    printf("%d\n", sizeof(p));   4
    sizeof(p + 1);   4
    sizeof(*p);   1
    sizeof(p[0]);  1
    sizeof(&p);   4  
    sizeof(&p + 1);    4
    sizeof(&p[0] + 1);    4
    return 0; 
}

*p存储的是a的地址,然后通过a指向整个字符串。

11、p也就是一个地址,所以是4/8

22、p + 1计算的是字符b,所以还是4/8

33、 *p就是字符串第一个字符,就是a,所以是1

44、访问数组某个元素时,arr[0], 也可以写作*arr,*(arr + 0),所以p[0]也就是*(p + 0),所以还是首元素地址,所以还是1。

55、取出p的地址,所以是4/8

66、&p+1,从p起始位置开始+1,也就是越过了一整个p所占据的空间,但最后还是地址,所以4/8

77、也是地址

换成strlen


int main()
{
    const char *p = "abcdef";
    printf("%d\n", strlen(p));   6
    strlen(p + 1);    5
    strlen(*p);   err报错
    strlen(p[0]);   err
    strlen(&p);    随机值
    strlen(&p + 1);  随机值
    strlen(&p[0] + 1);      5
    return 0;
}

&p,取出的是首元素地址,去计算,p的地址不同编译器有不同的地址,看地址:0x0043ff11,在内存中存储时就是11  ff   43   00,所以一个个字符读,读完前三个,遇到0,所以最终数值是3,所以这是个不定的数值。

&p + 1也一样随机值

&p[0] + 1,拿出首元素+1,也就是从b开始数,所以是5。

下一篇写二维数组

结束。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值