指针进阶练习

指针练习

一维数组

//一维数组
int a[] = {1,2,3,4};
printf("%d\n",sizeof(a));16----特例:数组名单独在sizeof内部时,计算的是整个数组的大小
    
printf("%d\n",sizeof(a+0));4/8----数组名是首元素的地址,在a+0是数组中1的地址,因为a+0是地址,所以sizeof(地址)的大小为4/8个字节
    
printf("%d\n",sizeof(*a));4----数组名是首元素的地址,*是第一个元素,所以计算的是第一个元素的大小
    
printf("%d\n",sizeof(a+1));4/8----数组名是首元素的地址,a+1是数组中2的地址,因为a+1是地址,所以sizeof(地址)的大小为4/8个字节
    
printf("%d\n",sizeof(a[1]));4----a[1]是数组中的第二个元素,所以计算的是第二个元素的大小

printf("%d\n",sizeof(&a));4/8----&a拿到的是整个数组的地址,但&a是地址,所以sizeof(地址)大小为4/8个字节
    
printf("%d\n",sizeof(*&a));16----拿出整个数组的地址,对整个数组的地址解引用
    因为8a中的a是数组首元素的地址,a<==>&a[0],*&a[0]相当于a[0],这样就相当于*&相互抵消
    
printf("%d\n",sizeof(&a+1));4/8----&a+1得到的是指向数组a后面那个位置的地址,因为是地址,所以sizeof(地址)的大小为4/8个字节
    
printf("%d\n",sizeof(&a[0]));4/8----&a[0]得到的是第一个元素的地址,因为是地址,所以sizeof(地址)的大小为4/8个字节
    
printf("%d\n",sizeof(&a[0]+1));4/8----&a[0]+1得到的是第二个元素的地址,因为是地址,所以sizeof(地址)的大小为4/8个字节

字符数组


## 字符数组

char arr[] = {'a','b','c','d','e','f'};
printf("%d\n", sizeof(arr));6----特例:arr数组名单独放在sizeof中,得到的是整个数组的大小

printf("%d\n", sizeof(arr+0));4/8----数组名是首元素地址,arr+0得到的是第一个元素的地址,因为是地址,所以sizeof(地址)的大小为4/8个字节
    
printf("%d\n", sizeof(*arr));1----数组名是首元素的地址,*arr得到的是第一个元素,sizeof(char)1个字节

printf("%d\n", sizeof(arr[1]));1----arr[1]是第二个元素的大小

printf("%d\n", sizeof(&arr));4/8----取出的是整个数组的地址,因为是地址,所以sizeof(地址)的大小为4/8个字节
    
printf("%d\n", sizeof(&arr+1));4/8----&arr拿到的是整个数组的地址,&arr+1指向的是数组后面的那一块空间的地址,因为是地址,所以sizeof(地址)得到的是4/8个字节
    
printf("%d\n", sizeof(&arr[0]+1));4/8----&arr[0]拿到的是数组首元素的地址,&arr[0]+1指向的是数组第二个元素的地址,因为是地址,所以sizeof(地址)得到的是4/8个字节

    
    
    关于strlen
char arr[] = {'a','b','c','d','e','f'};
printf("%d\n", strlen(arr));【随机值】因为在字符数组中并没有'\0'的存在,所以在计算长度的时候,得到的是一个随机值
       
printf("%d\n", strlen(arr+0));【随机值】arr是数组首元素的地址,arr+0得到的也是数组首元素的地址,因为在字符数组中没有'\0'的存在,所以在计算长度的时候,得到的是一个随机值
       
printf("%d\n", strlen(*arr));【编译错误】----*arr得到的是第一个字符'a',strlen(97),传给strlen的应该是地址,解引用得到a以后,a的地址是野指针
    
printf("%d\n", strlen(arr[1]));【编译错误】----arr[1]得到的是第二个字符'b' 传给strlen的应该是地址,解引用得到b以后,b的地址是野指针
    
printf("%d\n", strlen(&arr));【随机值】----&arr得到的是整个数组的地址,因为字符数组中没有'\0'的存在,所以在计算长度的时候,得到的是一个随机值
    
printf("%d\n", strlen(&arr+1));【随机值-6----&arr得到的是整个数组的地址,&arr+1指向的是字符数组后面那块空间的地址,所以在计算长度的时候,得到的是一个减去字符数组长度以后的大小,也就是随机值-6
    
printf("%d\n", strlen(&arr[0]+1));【随机值-1----&arr[0]得到的是数组的第一个元素的地址,&arr[0]+1得到的是第二个元素的地址,所以在计算长度的时候,得到的是一个减去第一个字符以后长度的大小,也就是随机值-1

char arr[] = "abcdef";
printf("%d\n", sizeof(arr));7----arr单独放在sizeof内部的时候,计算的是整个数组的大小,因为sizeof计算的是所占空间的大小,所以也包括'\0' 那么得到的就是7
    
printf("%d\n", sizeof(arr+0));4/8----arr是数组首元素的地址,arr+0得到的还是数组首元素的地址,因为是地址,所以sizeof(地址)得到的大小为4/8
    
printf("%d\n", sizeof(*arr));1----*arr是第一个元素,因为是char类型,所以是1
    
printf("%d\n", sizeof(arr[1]));1----arr[1]是数组中的第二个元素,因为是char类型,所以是1

printf("%d\n", sizeof(&arr));4/8----&arr是整个数组的大小,因为是地址,所以sizeof(地址)得到的大小为4/8个字节
    
printf("%d\n", sizeof(&arr+1));4/8----&arr+1指向的是数组后面那块空间的地址,因为是地址,所以sizeof(地址)得到的大小是4/8个字节
    
printf("%d\n", sizeof(&arr[0]+1));4/8----&arr[0]+1得到的是第二个元素的地址,因为是地址,所以sizeof(地址)得到的大小是4/8个字节
    
printf("%d\n", strlen(arr));6----strlen计算的是'\0'之前的元素个数,有6printf("%d\n", strlen(arr+0));6----strlen计算的是'\0'之前的元素个数,有6printf("%d\n", strlen(*arr));【编译错误】*arr得到的是第一个字符'a',strlen(97),传给strlen的应该是地址,解引用得到a以后,a的地址是野指针
    
printf("%d\n", strlen(arr[1]));【编译错误】----arr[1]得到的是第二个字符'b' 传给strlen的应该是地址,解引用得到b以后,b的地址是野指针
    
printf("%d\n", strlen(&arr));6----strlen计算的是'\0'之前的元素个数,有6printf("%d\n", strlen(&arr+1));【随机值】----指向的是数组后面那块空间的地址,不知道何时会遇到'\0',所以是随机值
    
printf("%d\n", strlen(&arr[0]+1));5----strlen计算的是'\0'之前的元素个数,有5

在这里插入图片描述

char *p = "abcdef";
printf("%d\n", sizeof(p));4/8----因为p是一个指针变量,指针变量的大小为4/8个字节,取决于编译器
    
printf("%d\n", sizeof(p+1));4/8----假设p的地址为0x0012ff40那么p+1就是0x12ff41  还是一个地址,是地址,sizeof(地址)的大小为4/8个字节
    
printf("%d\n", sizeof(*p));1----因为p是char*类型的,访问一个字节,那么一个字节就是a,就得到1
    
printf("%d\n", sizeof(p[0]));1----p[0]   <==>  *(p+0)  是首字符a的大小,a是字符,所以是1个字节
    
printf("%d\n", sizeof(&p));4/8----&p取出的是指针变量p的地址,应该用二级指针来保存,但是二级指针也是指针,所以是4/8个字节
    
printf("%d\n", sizeof(&p+1));4/8----&p+1得到的还是地址,但特殊的是,得到的是指针变量p跳过p变量空间,后面的那一块空间的地址,是地址,还是4/8个字节
    
printf("%d\n", sizeof(&p[0]+1));4/8----&p[0]是a的地址,&p[0]+1得到的是b的地址,是地址,就是4/8个字节
    
printf("%d\n", strlen(p));6----p里面放的是a的地址,所以传给strlen的也是a的地址,strlen计算的是'\0'之前的元素个数,有6printf("%d\n", strlen(p+1));5----p里面放的是a的地址,p+1得到的是b的地址,所以传给strlen的也是b的地址,strlen计算的是'\0'之前的元素个数,有5printf("%d\n", strlen(*p));【编译错误】----*arr得到的是第一个字符'a',strlen(97),传给strlen的应该是地址,解引用得到a以后,a的地址是野指针

printf("%d\n", strlen(p[0]));【编译错误】----*arr得到的是第一个字符'a',strlen(97),传给strlen的应该是地址,解引用得到a以后,a的地址是野指针
    
printf("%d\n", strlen(&p));【随机值】----&p得到的是p的地址,与字符串完全不是一块空间,不知道什么时候会遇到\0停下来,所以是随机值
    
printf("%d\n", strlen(&p+1));【随机值】----&p+1得到的是p加上1的地址,与字符串完全不是一块空间,不知道什么时候会遇到\0停下来,所以是随机值
    
printf("%d\n", strlen(&p[0]+1));5----&p[0]得到的是a的地址,a的地址+1得到的是b的地址,trlen计算的是'\0'之前的元素个数,有5

二维数组

在这里插入图片描述

//二维数组
int a[3][4] = {0};
printf("%d\n",sizeof(a));48----数组名单独放在sizeof内部,计算的是整个数组的大小 所以是48
    
printf("%d\n",sizeof(a[0][0]));4----arr[0][0]是数组的第一行的第一列元素,是int类型的,所以是4

printf("%d\n",sizeof(a[0]));16----我们在访问二维数组的时候,arr[0][j] j的取值范围为0-3 在访问一维数组的时候,j的取值范围为0-9 二维数组的arr[0]  arr[1]   arr[2]就是二维数组每一行数组的数组名
    数组名单独放在sizeof内部,计算的是那一行所有元素的大小,所以是16
     
printf("%d\n",sizeof(a[0]+1));4/8----a[0] <==>&a[0][0],&a[0][0]+1得到的是第一行第二个元素的地址,因为是地址,所以sizeof(地址)的大小为4/8个字节
    
    printf("%d\n",sizeof(*(a[0]+1)));4----a[0] <==>&a[0][0],&a[0][0]+1得到的是第一行第二个元素的地址,因为是地址,对其进行解引用,得到的就是int类型的大小

在这里插入图片描述

printf("%d\n",sizeof(a+1));【】----a是二维数组的数组名,a表示首元素的地址,二维数组的首元素是它的第一行,a就是第一行的地址,数组的地址+1得到的是第二行的地址,因为是地址,所以是4/8个字节
    
printf("%d\n",sizeof(*(a+1)));16----*(a+1) <==> a[1] 所以sizeof(*(a+1)) <==> sizeof(a[1]),a[1]是第二行的数组名,计算的是第二行的大小
    
printf("%d\n",sizeof(&a[0]+1));4/8----&a[0]拿到的是第一行的地址,&a[0]+1得到的是第二行元素的地址,因为是地址,所以是4/8个字节

printf("%d\n",sizeof(*(&a[0]+1)));4----&a[0]拿到的是第一行的地址,&a[0]+1得到的是第二行元素的地址,对其进行解引用,得到的就是4

printf("%d\n",sizeof(*a));16----a是首元素的地址,二维数组的首元素是第一行元素,对第一行的地址进行解引用,拿到的就是第一行,第一行单独放在sizeof内部,得到的就是16

printf("%d\n",sizeof(a[3]));16----虽然没有第三行,但是会根据类型分析,得到16
总结: 数组名的意义:
1. sizeof(数组名),这里的数组名表示整个数组,计算的是整个数组的大小。
2. &数组名,这里的数组名表示整个数组,取出的是整个数组的地址。
3. 除此之外所有的数组名都表示首元素的地址。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值