【指针和数组笔试题(2)】详解指针、数组笔试题


前言

来到第二章,继续学习指针和数组笔试题


第一组题

#include<stdio.h>
int main()
{
    
    
	char arr[] = "abcdef";//里面的放的是[a b c d e f \0]
printf("%d\n", strlen(arr));

没有单独放在sizeof内部,所以表示首元素地址,strlen统计的是在字符串中\0之前的字符的个数,所以结果是6
2.

printf("%d\n", strlen(arr+0));

arr表示首元素地址,arr+0也表示首元素地址,结果仍是6
3.

//printf("%d\n", strlen(*arr));

arr表示首元素地址,*arr表示首元素,就是字符a,传的是ASCII码值,非法访问内存,是错误代码
4.

printf("%d\n", strlen(arr[1]));

arr[1]是数组第二个元素,也是非法访问内存,是错误代码
5.

printf("%d\n", strlen(&arr));

&arr是数组的地址,但strlen是从首元素地址开始访问的,遇到\0停下,结果是6
6.

printf("%d\n", strlen(&arr+1));

&arr是数组地址,&arr+1跳过整个数组,从\0后面向后访问,后面是未知的,所以是随机值
如下图:
在这里插入图片描述
7.

printf("%d\n", strlen(&arr[0]+1));

&arr[0]表示数组首元素地址,&arr[0]+1表示第二个元素地址,意思是从第二个元素地址向后访问,统计了bcdef,5个字符

	return 0;
}

在这里插入图片描述

总结:strlen访问的是地址,统计的是在字符串中\0之前的字符的个数。如果访问的是元素本身,就会造成非法访问内存。


第二组题

int main()
{
    
       

char* p = "abcdef";//[a b c d e f \0]

在这里插入图片描述
1.

printf("%d\n", sizeof(p));

p是char类型的指针变量
p是指针变量,大小是4/8个字节
2.

printf("%d\n", sizeof(p + 1));

p是从首元素地址访问的,p+1就是第二个元素地址,就是’b’的地址,是地址就是4/8个字节
如下图:

在这里插入图片描述
3.

printf("%d\n", sizeof(*p));

p是首元素地址,*p就是首元素,就是字符’a’,访问的不是地址,是元素本身,计算的是大小,char类型是一个字节
4.

printf("%d\n", sizeof(p[0]));//p[0]=*(p+0)

p[0]是首元素,大小是一个字节
5.

printf("%d\n", sizeof(&p));

p存放的是字符串的地址,&p是char**类型,存放的是p的地址,不是字符串的地址,是地址就是4/8个字节
6.

printf("%d\n", sizeof(&p + 1));

&p是从p的地址开始的,存的是p的整个地址,&p + 1,跳过整个地址,从p的地址后面往后访问地址,是地址就是4/8个字节。
要区分好p+1和&p+1的区别。
如下图:
在这里插入图片描述
7.

 printf("%d\n", sizeof(&p[0] + 1));

&p[0]指向数组首元素地址,&p[0] + 1指向数组第二个元素地址,得到’b’的地址,是地址就是4/8个字节

	return 0;
}

总结:p是指针变量,本身就是一个地址,&p也是一个地址,但它们存放的不是同一个地址。p存放的是某个数组的地址,&p存放的是p的地址。
在这里插入图片描述


第三组题

int main()
{
    
    
	char* p = "abcdef";//[a b c d e f \0]
printf("%d\n", strlen(p));

p是一个指针,存放a b c d e f \0的地址,strlen从a开始访问,遇到\0停下,所以访问了a b c d e f6个字节
2.

printf("%d\n", strlen(p + 1));

p+1是’b’的地址,意思是从p[1]开始向后访问,访问了b c d e f 5个字节3.

//	printf("%d\n", strlen(*p));

p是a的地址,*p是字符’a’,非法访问内存
4.

//	printf("%d\n", strlen(p[0]));

p[0]=*p=‘a’,所以也是非法访问内存
5.

printf("%d\n", strlen(&p));

p存放的是字符串的地址,&p=char**,存放的是p的地址,但是编译器并不知道p的地址是什么,所以strlen访问到的是一个随机值
6.

printf("%d\n", strlen(&p + 1));

&p+1f跳过了p的地址,从p的地址后面往后访问地址,p后面的地址编译器更不知道了,所以也是随机值
7.

printf("%d\n", strlen(&p[0] + 1));

&p[0]是从’a’的地址向后访问,&p[0] + 1是从’b’的地址向后访问,访问了b c d e f 5个字节

return 0;
}

在这里插入图片描述


二维数组(难点)

int main()
{
    
    
int a[3][4] = {
    
     0 };

三行四列的数组,元素都是0
2.

printf("%d\n", sizeof(a));

数组名单独放在sizeof内部,表示整个数组大小,每个元素是整型,344=48
3.

printf("%d\n", sizeof(a[0][0]));

0行0列的元素,大小是4个字节
4.

printf("%d\n", sizeof(a[0]));

把二维数组的每一行看作是一个元素,三行就是三个元素,a[0]就是二维数组的第一行的数组名,注意不是首元素,数组名单独放在sizeof内部,计算整个数组大小,是4*4=16
5.

printf("%d\n", sizeof(a[0]+1));

a[0]没有单独放在sizeof内部,是第一行的首元素地址,a[0]+1是第一行第二个元素的地址,是地址就是4/8个字节
6.

printf("%d\n", sizeof(*(a[0] + 1)));

a[0]+1是第一行第二个元素的地址,*(a[0] + 1)就是第一行第二个元素,大小是4个字节
7.

printf("%d\n", sizeof(a+1));

a是数组首元素的地址,是二维数组第一行的地址,a+1就是二维数组第二行的地址,是地址就是4/8个字节
8.

printf("%d\n", sizeof(*(a + 1)));

a+1是二维数组第二行的地址,(a + 1)是二维数组第二行的元素大小,大小是44=16
9.

printf("%d\n", sizeof(&a[0] + 1));

注意不要把a[0]看作是数组首元素,在二位数组这里,a[0]是数组名,&数组名+1跳过整个数组,表示的是二维数组第二行的地址,是地址就是4/8个字节
10.

printf("%d\n", sizeof(*(&a[0] + 1)));

&a[0] + 1表示的是二维数组第二行的地址,(&a[0] + 1)表示二维数组第二行的元素,计算大小,44=16
11.

printf("%d\n", sizeof(*a));

没有单独放在sizeof内部,没有&修饰,这里的a是二维数组首元素地址,就是第一行的地址,a就是第一行,大小是44=16
12.

printf("%d\n", sizeof(a[3]));

a[3]表示二维数组第四行的数组名,大小是4*4=16
return0;
}

在这里插入图片描述

总结

以上就是今天的指针和数组笔试题,二维数组是难点,需要花时间多理解。

猜你喜欢

转载自blog.csdn.net/2301_76496134/article/details/131895498