1,一维数组
先看一下一个整型数组关于数组名的表达式在内存中所占的字节数
#include<stdio.h> #include<stdlib.h> int main() { int a[] = { 1, 2, 3, 4 }; printf("%d\n", sizeof(a)); // 16 在sizeof中,数组名a不发生降级,代表整个数组 printf("%d\n", sizeof(a+0)); // 4 在sizeof中,如果是关于a的表达式,那a就代表数组首元素的地址,就是一个整型指针,向后偏移0,不变 printf("%d\n", sizeof(*a)); // 4 a代表数组首元素的地址,解引用a访问a[0]的内容,一个整型 printf("%d\n", sizeof(a+1)); // 4 a代表数组首元素的地址,加1向后偏移一个整型空间,表示a[1]的地址 printf("%d\n", sizeof(a[1])); // 4 a[1]是整型,占4个字节 printf("%d\n", sizeof(&a)); // 4 数组名在取地址时也不发生降级,&a取出的是整个数组的地址,与a[0]的地址相同 printf("%d\n", sizeof(&a+1)); // 4 &a是数组的地址,类型是数组指针,&a+1要跳过整个数组,即跳过16个字节,但依然是个地址,所以还是4个字节 printf("%d\n", sizeof(&a[0])); // 4 取出a[0]的地址,占4个字节 printf("%d\n", sizeof(&a[0]+1)); // 4 取出a[0]的地址,向后偏移4个字节,指向a[1]的地址 printf("%d\n", sizeof(*&a)); // 4 取出整个数组的地址,再解引用,相当于访问整个数组 system("pause"); return 0; }
注意:数组名在以下两个情况下不发生降级,代表整个数组,
(1)sizeof(a)中,a代表整个数组;
(2)在&a中,代表整个数组的地址;
在其他地方,数组名都代表数组首元素的地址。
关于为什么&a+1,&a是数组的地址,&a+1就要跳过整个数组,可以这样理解
int *p = NULL; p + 1;
p是一个整型指针,给p+1就是加上一个整型指针所占的字节数,那么同样&a+1就要加上整个数组所占的字节数,即跳过整个数组。
上面说了&a取出来的地址和a的地址相同,但是有一点不同的是,它们向后偏移的字节数并不相同。例如:
#include<stdio.h> #include<stdlib.h> int main() { int a[] = { 1, 2, 3, 4 }; printf("%p\n", a); printf("%p\n", &a); printf("%p\n", a+1); printf("%p\n", &a+1); system("pause"); return 0; }
从上面就可以看出来,在&a+1加了整个数组所占字节数,对a+1就向后偏移了一个整型空间。
2,指针
在定义指针时,
int arr[]={ 1, 2, 3, 4 }; int *p = arr;//*与p结合,不是和类型int结合 *p=20;//这样的赋值是错误的,因为不知道p到底指向哪里 *p++;//无意义,先解引用,再对p所指向的内容自加 p++;//有意义,访问下一个空间
指针加1等价于加(1*sizeof(arr))
对关于指针的表达式在内存中所占的字节数:
#include<stdio.h> #include<stdlib.h> #include<string.h> int main() { char ch[] = "abcdef"; printf("%d\n", sizeof(ch[0])); // 1 代表字符‘a‘ printf("%d\n", sizeof(&ch)); // 4 是数组地址,放在指针变量里,占4个字节 printf("%d\n", sizeof(*ch)); // 1 在这儿ch代表数组首元素地址,*ch访问ch[0]=‘a‘ printf("%d\n", sizeof(&ch+1)); // 4 &ch+1向后偏移整个数组所占字节数 printf("%d\n", sizeof(ch+1)); // 4 ch代表数组首元素地址,是一个指针,加1依然是个指针 printf("%d\n", sizeof(ch)); // 7 六个字符还有一个‘\n‘ printf("%d\n", strlen(ch)); // 6 有效字符长度 printf("%d\n", strlen(&ch)); // 6 &ch与ch的地址相同,从这个位置开始向后找‘\0‘ printf("%d\n", strlen(&ch + 1)); // 随机值 ,因为&ch+1向后偏移整个数组的大小,不确定在什么时候遇到‘\0‘ printf("%d\n", strlen(ch+1)); // 5 首元素地址加1,向后偏移一个字节,从ch[1]到ch[5],长度为5 system("pause"); return 0; }
本文出自 “Stand out or Get out” 博客,转载请与作者联系!
原文地址:http://jiazhenzhen.blog.51cto.com/10781724/1719729