思路大纲:
1.sizeof和strlen的对比
但是需要强调一下哈:两者的返回类型都是size_t类型的,两个无符号类型的整型数字相减,在数学上得到的答案是一个负数,在计算机上是一个很大的正数,因为对于计算机而言无符号整形不存在负数。
2.数组和指针笔试题(借用sizeof与strlen进行体会)
编号1:
int main() { int a[] = { 1,2,3,4 }; printf("%d\n", sizeof(a));//16, 计算的是整个数组的内存大小 printf("%d\n", sizeof(a + 0));// 4/8 a是数组名,代表首元素的地址,+0操作之后还是数组首元素地址 printf("%d\n", sizeof(*a));//4 *a,对数组名(数组首元素地址)进行解引用操作,拿到的是数字1 printf("%d\n", sizeof(a + 1));//4/8 a是数组名,代表数组首元素地址,+1操作之后拿到的是数组第二个元素的地址 printf("%d\n", sizeof(a[1]));//4 a[1]==*(a+1),拿到的是数组第二个元素 printf("%d\n", sizeof(&a));//4/8 取地址,是一个地址,是整个数组的地址 printf("%d\n", sizeof(*&a));//16 *与&抵消了 printf("%d\n", sizeof(&a + 1));//4/8 是地址 printf("%d\n", sizeof(&a[0]));//4/8 是数组第一个元素的地址 printf("%d\n", sizeof(&a[0] + 1));//4/8 是数组第二个元素的地址 return 0; }
编号2:
char arr[] = { 'a','b','c','d','e','f' }; printf("%d\n", sizeof(arr));//6 sizeof(数组名),计算的整个数组的大小 printf("%d\n", sizeof(arr + 0));//4/8 arr是数组首元素的地址,+0操作之后仍然是数组首元素的地址, printf("%d\n", sizeof(*arr));//1 arr是数组首元素地址,解引用操作,得到的是数组第一个元素,其内存大小为1 printf("%d\n", sizeof(arr[1]));//1 arr[1]==*(arr+1)得到的是数组第二个元素,其类型为char类型,内存大小为1 printf("%d\n", sizeof(&arr));//4/8 这是整个数组的地址 printf("%d\n", sizeof(&arr + 1));//4/8 某个地址 printf("%d\n", sizeof(&arr[0] + 1));//4/8 地址
编号3:
char arr[] = { 'a','b','c','d','e','f' }; printf("%d\n", strlen(arr));//未知数 strlen函数以/0为结束标志,该字符数组中没有添加/0,后面内存某个位置有/0 printf("%d\n", strlen(arr + 0));//未知数 strlen函数以/0为结束标志,该字符数组中没有添加/0,后面内存某个位置有/0 //printf("%d\n", strlen(*arr));//error strlen函数的参数需要给一个地址,arr是数组首元素的地址,但是*a得到的是字符‘a’,也就是strlen把97当作一个地址吗?这种写法是错误的 //printf("%d\n", strlen(arr[1]));//error strlen函数的参数需要一个地址,而不是一个字符 printf("%d\n", strlen(&arr));//未知数 printf("%d\n", strlen(&arr + 1));//未知数-6 printf("%d\n", strlen(&arr[0] + 1));//未知数-1
编号4:
char arr[] = "abcdef"; printf("%d\n", sizeof(arr));//7 sizeof计算的是数组所占内存大小,“字符串”这种写法,编译器默认后面有个\0 printf("%d\n", sizeof(arr + 0));//4/8 arr是一个数组名,是一个地址,+0操作之后还是那个地址而已 printf("%d\n", sizeof(*arr));//1 arr是数组首元素的地址,解引用操作之后,得到的是字符a,其所占内存大小为1 printf("%d\n", sizeof(arr[1]));//1 数组第二个元素所占内存大小,其所占内存大小为1 printf("%d\n", sizeof(&arr));//4/8 内存 printf("%d\n", sizeof(&arr + 1));//4/8 内存 printf("%d\n", sizeof(&arr[0] + 1));//4/8 内存
编号5:
int main() { char arr[] = "abcdef";//表面上看是6个字符,实际上arr数组是七个字符的字符串,后面还有一个\0 printf("%d\n", strlen(arr));//6 strlen函数计算的是/0之前字符个数 printf("%d\n", strlen(arr + 0));//6 strlen函数需要传入的是一个指针,跟第一个没啥区别 //printf("%d\n", strlen(*arr));//error strlen函数需要一个地址,但是解引用数组名,拿到的是字符a,也就是97,可能会把97当作一个地址来进行使用。 //printf("%d\n", strlen(arr[1]));//error strlen函数需要传入地址,而不是拿到arr数组中的某个值 printf("%d\n", strlen(&arr));//6 传入的是整个数组的地址,但是这个整个数组的地址跟arr是一样的 printf("%d\n", strlen(&arr + 1));//未知数 &arr拿到的是整个数组的地址,+1操作之后,跳过的是一个char(*)[7]的一个指针类型,会直接跳过整个数组 printf("%d\n", strlen(&arr[0] + 1));//5 拿到数组首元素地址再加一操作,得到的是数组第二个元素的地址,6-1=5 return 0; }
编号6:
char* p = "abcdef";// 这是一个指向常量字符串的指针 printf("%d\n", sizeof(p));//4/8 p是一个指向常量字符串的指针,其大小取决与编译环境,如果是x86,是四个字节;如果是x64的话,是8个字节 printf("%d\n", sizeof(p + 1));//4/8 p+1也是一个指针 printf("%d\n", sizeof(*p));//1 *p找到的是字符a,其所占的内存大小为1字节 printf("%d\n", sizeof(p[0]));//1 p[0]==*(p+0),所以说跟上面那个没什么差别 printf("%d\n", sizeof(&p));//4/8 这是一个指针,char**类型的指针 printf("%d\n", sizeof(&p + 1));//4/8 与上面同理 printf("%d\n", sizeof(&p[0] + 1));//4/8 这是一个地址(指针)
编号7:
char* p = "abcdef"; printf("%d\n", strlen(p));//6 strlen函数以找\0为结束标志,strlen函数需要一个地址参数 printf("%d\n", strlen(p + 1));//5 p+1指向的是字符b //printf("%d\n", strlen(*p));//error 拿到的是一个字符,并不是地址 //printf("%d\n", strlen(p[0]));//error 拿到的不是一个地址 printf("%d\n", strlen(&p));//未知 拿到的是地址,但不是字符串地址,因而不能确定 printf("%d\n", strlen(&p + 1));//未知 拿到的是地址,但不是字符串的地址,不确定 printf("%d\n", strlen(&p[0] + 1));//5 拿到数组第二个元素地址
编号8:
int a[3][4] = { 0 }; printf("%d\n", sizeof(a));//48 sizeof(数组名),得到的是整个数组大小所占内存空间 printf("%d\n", sizeof(a[0][0]));//4 a[0][0]拿到的是数组第一个元素地址 printf("%d\n", sizeof(a[0]));//16 a[0]拿到的是二维数组的第一行,当然这里理解需要结合二维数组本质去理解 printf("%d\n", sizeof(a[0] + 1));//4/8 因为a[0]是一个地址,+1之后仍然是一个地址 printf("%d\n", sizeof(*(a[0] + 1)));//4 解引用拿到一个具体的元素数值 printf("%d\n", sizeof(a + 1));//4/8 地址 printf("%d\n", sizeof(*(a + 1)));//16 拿到整个第二行 printf("%d\n", sizeof(&a[0] + 1));//4/8 地址 printf("%d\n", sizeof(*(&a[0] + 1)));//16 拿到整个第二行地址,在进行解引用操作 printf("%d\n", sizeof(*a));//16 拿到的是整个第一行,4*4=12 printf("%d\n", sizeof(a[3]));//16 这里不存在越界,因为sizeof不关注内存中存放的内容
3.指针运算笔试题
转链接:指针运算笔试题