目录
一.必备知识
1. 数组名
数组名表示整个数组的情况只有两种:
sizeof(数组名) --计算的是整个数组的大小
&数组名 --取出的是整个数组的地址
2.sizeof
用于计算类型或者对象的大小
sizeof是运算符,不是函数
3.strlen
计算字符串的长度,找到\0为止。
strlen作为函数,接收的是一个字符串的地址,返回的是int。
二.一维数组
#include<stdio.h>
int main()
{
int a[] = { 1,2,3,4 };
printf("%d\n", sizeof(a)); // 16sizeof(数组名)代表计算整个数组大小
printf("%d\n", sizeof(a + 0)); // 4/8a代表首元素地址,偏移0个地址,计算地址,一个地址4字节
printf("%d\n", sizeof(*a)); // 4/8a代表首元素地址,*a表示对a[0]解引用,一个元素int类型,4字节
printf("%d\n", sizeof(a + 1)); // 4/8a代表首元素地址,偏移1个地址,计算地址,一个地址4字节
printf("%d\n", sizeof(a[1])); // 4
a[1]代表第二个元素,即2,2是int型。4字节printf("%d\n", sizeof(&a)); // 4/8
&a,取出的是整个数组的地址,计算地址,地址4字节printf("%d\n", sizeof(*&a)); // 16
&a,取出整个数组的地址,解引用,取出整个数组,整个数组是int型即4*4=16字节printf("%d\n", sizeof(&a + 1)); // 4/8
&a取出整个数组的地址,+1跳过这个数组,此时已不在这个数组之内,但sizeof不会进行 访问,所以不会非法访问错误。而计算地址,地址4字节printf("%d\n", sizeof(&a[0])); // 4/8
&a[0]计算第一个元素的地址,地址4字节printf("%d\n", sizeof(&a[0] + 1)); // 4/8&a[0]取出第一个元素的地址,偏移1个地址,计算地址,地址4字节
三.字符数组
char arr[] = {'a','b','c','d','e','f'};printf("%d\n", sizeof(arr)); // 6sizeof(数组名)表示计算整个数组大小,一个元素char大小,即6*1=6字节printf("%d\n", sizeof(arr+0)); // 4/8arr表示数组首元素地址,偏移0个地址,计算地址,一个地址4字节printf("%d\n", sizeof(*arr)); // 1arr表示首元素地址,对首元素地址解引用 取出'a',它的大小是1字节printf("%d\n", sizeof(arr[1])); // 1计算第二个元素的大小,1字节printf("%d\n", sizeof(&arr)); // 4/8&arr表示取出整个数组的地址,计算地址,地址4字节printf("%d\n", sizeof(&arr+1)); // 4/8&arr表示取出整个数组的地址,偏移1个地址,此时已不在arr数组之内,但并没有访问,不会形成非法访问错误,计算地址,地址4字节printf("%d\n", sizeof(&arr[0]+1)); // 4/8&arr[0]取出一个元素的地址,偏移1个地址,计算地址,地址4字节printf("%d\n", strlen(arr)); // 随机数数组名没有放在sizeof里,代表首元素的地址,看似为arr的长度,其实数组arr没有\0结尾,strlen找不到结束标志,会一直计算,知道找到\0为止。printf("%d\n", strlen(arr+0)); // 随机数首元素地址偏移0个地址,代表首元素地址,和上面一种情况printf("%d\n", strlen(*arr)); // errarr表示首元素地址,解引用表示第一个元素,strlen接收的是地址,非法printf("%d\n", strlen(arr[1])); // errarr[1]是第二个元素,不是地址,非法printf("%d\n", strlen(&arr)); // 随机数&arr取出整个数组的地址,实质上传过去的也还是首元素地址,但arr没有\0结束,将会生成随机数。printf("%d\n", strlen(&arr+1)); // 随机数&arr取出整个数组的地址,+1偏移1个地址,不知道在哪去了,当然也不知道\0在哪,还是随即数printf("%d\n", strlen(&arr[0]+1));&arr[0]取出第一个元素的地址,偏移1个地址,但是arr还是没有\0, 还是随机数
char arr[] = "abcdef";printf("%d\n", sizeof(arr)); // 7(6+1)别忘记\0sizeof(数组名)表示计算整个数组的大小printf("%d\n", sizeof(arr+0)); // 4/8arr表示首元素地址,偏移0个地址,表示第一个元素地址大小,4字节printf("%d\n", sizeof(*arr)); // 1arr表示首元素地址,解引用表示第一个元素,第一个元素char类型,1个字节printf("%d\n", sizeof(arr[1])); // 1arr[1]表示第二个元素,即'b' ,1个字节printf("%d\n", sizeof(&arr)); // 4/8&arr取出整个数组的地址,传过去的其实还是数组首元素的地址,地址4个字节printf("%d\n", sizeof(&arr+1)); // 4/8&arr取出整个数组的地址,+1偏移一个地址,计算的还是地址,地址4个字节printf("%d\n", sizeof(&arr[0]+1)); // 4/8&arr[0]取出第一个元素的地址,+1偏移1个地址,计算的还是地址,地址4个字节printf("%d\n", strlen(arr)); // 6arr代表首元素地址,传首元素地址,计算arr的长度,6printf("%d\n", strlen(arr+0)); // 6arr代表首元素地址,+0偏移0个地址,还是计算arr的长度, 6printf("%d\n", strlen(*arr)); // err首元素解引用,没有传地址,错误printf("%d\n", strlen(arr[1])); // errarr[1]:第二个元素,没有传地址,错误printf("%d\n", strlen(&arr)); // 6&arr取出arr的地址,计算的是arr的长度, 6printf("%d\n", strlen(&arr+1)); // 随机数&arr取出arr地址,+1偏移一个地址,已不在arr之内,随机数printf("%d\n", strlen(&arr[0]+1)); // 5&arr[0]取出第一个元素的地址,+1偏移1个地址,计算b-f的长度 5
char* p = "abcdef";
printf("%d\n", strlen(p)); // 6
求字符串长度
printf("%d\n", strlen(p + 1)); // 5
p + 1是b的地址,求字符串长度就是5
printf("%d\n", strlen(*p)); // err
*p是'a'
printf("%d\n", strlen(p[0])); // err
同上一个
printf("%d\n", strlen(&p)); // 随机值
&p拿到的是p这个指针变量的起始地址,从这里开始求字符串长度完全是随机值
printf("%d\n", strlen(&p + 1)); // 随机值
&p+1是跳过p变量的地址,从这里开始求字符串长度也是随机值
printf("%d\n", strlen(&p[0] + 1)); // 5
&p[0] + 1是b的地址,从b的地址向后数字符串的长度是5
printf("%d\n", sizeof(p)); // 4/8
p是指针变量,大小就是4/8字节
printf("%d\n", sizeof(p + 1)); // 4/8
p + 1是b的地址,是地址,就是4/8个字节
printf("%d\n", sizeof(*p)); // 1
*p是'a',sizeof(*p)计算的是字符的大小,是1字节
printf("%d\n", sizeof(p[0])); // 1
p[0]-->*(p+0) --> *p 就同上一个,1字节
printf("%d\n", sizeof(&p)); // 4/8
&p是二级指针,是指针大小就是4/8
printf("%d\n", sizeof(&p + 1)); // 4/8
&p + 1是跳过p变量后的地址,4/8字节
printf("%d\n", sizeof(&p[0] + 1)); //4/8
p[0]就是‘a’,&p[0]就是a的地址,+1,就是b的地址,是地址就是4/8
四.二维数组
int a[3][4] = {0};printf("%d\n",sizeof(a)); // 12*4=48sizeof(数组名)表示计算整个数组的大小printf("%d\n",sizeof(a[0][0])); // 4a[0][0]表示第一行第一个元素的大小,元素是int型的,4字节printf("%d\n",sizeof(a[0])); // 16sizeof(a[0])表示计算数组a[0]的大小,为4*4=16printf("%d\n",sizeof(a[0]+1)); // 4/8a[0]没有单独放在sizeof内部,表示数组a[0]首元素地址,即a[0][0]的地址,+1表示a[0][1]的地址,地址 4/8字节printf("%d\n",sizeof(*(a[0]+1))); // 4其实就是对上题加一个解引用,求的是a[0][1]的大小是 4字节printf("%d\n",sizeof(a+1)); // 4/8a表示数组a的首地址,即第一行的地址,+1表示第二行的地址,地址4/8字节printf("%d\n",sizeof(*(a+1))); // 16对上题加一个解引用,即求第二行的大小,即4*4=16字节printf("%d\n",sizeof(&a[0]+1)); // 4/8&a[0]表示第一行的地址,+1表示第二行的地址,地址是4/8字节printf("%d\n",sizeof(*(&a[0]+1))); // 16对上题加一个解引用,表示第二行的大小,即4*4=16字节printf("%d\n",sizeof(*a)); // 16a表示数组a的首地址,即第一行的地址, 对地址解引用 求第一行的大小 4*4=16printf("%d\n",sizeof(a[3])); // ?sizeof(a[3])表示计算数组a[3]的大小,即便a[3]不在数组范围内,但不构成非法访问,正常计算,但我们不知道第四行是什么东西,所以不得解