目录
- 一维数组于指针的一些题
- 二维数组于指针的一些题
一维数组于指针的一些题
对数组名的理解
数组名表示首元素地址 //两个例外: //sizeof(数组名):表示计算整个数组的大小 //&数组名:这里取的也是整个数组的大小,除了他两以外其他所有数组名都是表示首元素地址的
//数组名表示首元素地址
//两个例外:
//sizeof(数组名):表示计算整个数组的大小
//&数组名:这里取的也是整个数组的大小
int main()
{
int a[] = { 1,2,3,4 };
printf("%d\n", sizeof(a));//16
printf("%d\n", sizeof(a + 0));//(a+0)这里的a就是首元素地址 4
printf("%d\n", sizeof(*a));//4
printf("%d\n", sizeof(a + 1));//4
printf("%d\n", sizeof(a[1]));//4
printf("%d\n", sizeof(&a));//4,地址在32位机器上只有4字节
printf("%d\n", sizeof(*&a));//16//整个数组的大小
printf("%d\n", sizeof(&a + 1));//4相当于跳过了整个字节,但是他任然是个地址,是地址在32位机器上任然是4字节
printf("%d\n", sizeof(&a[0]));//4
printf("%d\n", sizeof(&a[0] + 1));//4
return 0;
}
strlen是一个库函数,应用方法strlen(里面的参数必须是个地址)
strlen求字符数组长度时,先找到首元素的地址然后向后一直计算,直到碰到’\0’才会停止,然后取计算\0前面的字符串个数(字符串的\0,是要自己写的)
char arr[6] = { 'a','b','c','d','e','f' };
printf("%d\n", strlen(arr));//随机数,因为char arr[] = { 'a','b','c','d','e','f' };里面没有写\0,所以他计算到最后一个字符的时候不会停止,就越界了,
printf("%d\n", strlen(arr + 0));//随机数 和第一个一样,注意strlen(数组名);里面的数组名就是首元素地址
printf("%d\n", strlen(*arr));//非法访问 strlen函数需要的参数应该是个地址,而传给他的却是字符a,字符a的ASCII值为97,那么就是把97作为地址传给了strlen函数,就发生了非法访问
printf("%d\n", strlen(arr[1]));//非法访问 跟上面一样
printf("%d\n", strlen(&arr));//随机值 虽然&arr取出的是整个数组的地址,但是他任然是用第一个元素的地址来表示的,所以传过去后任然认为从第一个元素开始算
printf("%d\n", strlen(&arr + 1));//随机值
printf("%d\n", strlen(&arr[0] + 1));//随机值
字符串数组里的\0是可以省略的,里面默认有\0
sizeof在计算字符串数组时,是要把\0和空格都计算在里面的,
strlen计算字符串数组时,计算空格,但是不计算\0,只计算\0之前的元素
char arr[] = "abcdef";
printf("%d\n", sizeof(arr));//7
printf("%d\n", sizeof(arr + 0));//4
printf("%d\n", sizeof(*arr));//1
printf("%d\n", sizeof(arr[1]));//1
printf("%d\n", sizeof(&arr));//4
printf("%d\n", sizeof(&arr + 1));//4
printf("%d\n", sizeof(&arr[0] + 1));//4
printf("%d\n", strlen(arr));//6
printf("%d\n", strlen(arr + 0));//6
//printf("%d\n", strlen(*arr));//非法
//printf("%d\n", strlen(arr[1]));//非法
printf("%d\n", strlen(&arr));//6
printf("%d\n", strlen(&arr + 1));//已经跳出了这个字符串数组 随机值
printf("%d\n", strlen(&arr[0] + 1));//5
char* p = "abcdef";
printf("%d\n", sizeof(p));//4 p是一个指针变量
printf("%d\n", sizeof(p + 1));// 4 相当于b的地址
printf("%d\n", sizeof(*p));// *p就是a,a为char类型,所以大小为1
printf("%d\n", sizeof(p[0]));//p[0]=*(p+0) 就是a,a为char类型,所以大小为1
printf("%d\n", sizeof(&p));//是地址大小就是4
printf("%d\n", sizeof(&p + 1));//&p后就和字符串没有关系了,就相当于把指针变量p的地址取出来放到一个指针里,然后再对这个指针+1,当然他也是一个地址,所以大小任然为4
printf("%d\n", sizeof(&p[0] + 1));//相当于a的地址再+1 得到的是b的地址 大小4
printf("%d\n", strlen(p));//6 p指向的是a的地址,所以从a的地址处开始计算
printf("%d\n", strlen(p + 1));//5 从b的地址处开始计算
printf("%d\n", strlen(*p));//*p=a 非法访问
printf("%d\n", strlen(p[0])); //p[0] = *(p + 0)=a 非法访问
printf("%d\n", strlen(&p));//p的地址在那我们并不清楚,所以从&p的地方开始算到底在哪里可以遇到\0也不清楚 所以是随机值
printf("%d\n", strlen(&p + 1));//p的地址在那我们并不清楚,所以从+1的地方开始算到底在哪里可以遇到\0也不清楚。所以是随机值
printf("%d\n", strlen(&p[0] + 1));//a的地址+1=b的地址,从b的地址算起为5
二维数组于指针的一些题
int a[3][4] = { 0 };
printf("%d\n", sizeof(a));//sizeof(数组名)计算的是真个数组的大小:3*4*4=48
printf("%d\n", sizeof(a[0][0]));//第一行第一列的那个元素,int类型 4字节
printf("%d\n", sizeof(a[0]));// sizeof(a[0]), 就是求第一行的大小 16个字节
printf("%d\n", sizeof(a[0] + 1));// 这里的a[0]就相当于第一行的首元素地址, + 1就是第一行第二个元素的地址,当然地址只能是4\8
printf("%d\n", sizeof(*(a[0] + 1)));//4
printf("%d\n", sizeof(a + 1));//sizeof(a+1),这里的a是二维数组首元素的地址,也就是第一行的地址,+1就是第二行的地址 4
printf("%d\n", sizeof(*(a + 1)));//sizeof(*(a+1))就相当于是求第二行这个数组的总大小16
printf("%d\n", sizeof(&a[0] + 1));//&a[0]取的是第一行数组的地址,+1就是第二行数组的地址 4
printf("%d\n", sizeof(*(&a[0] + 1))); //就相当于是求第二行这个数组的总大小16
printf("%d\n", sizeof(*a));//*第一行数组,16
printf("%d\n", sizeof(a[3]));//行数到a[2]就没有了,但是sizeof计算时并不是要去找到那么数字带入计算而是通过类型来计算的,显然a[3]也是int a[4]类型的 16