征服指针——指针和数组练习

Posted 小倪同学 -_-

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了征服指针——指针和数组练习相关的知识,希望对你有一定的参考价值。

一维数组

下面输出是什么

int main()
{
	int a[] = { 1, 2, 3, 4 };
	printf("%d\\n", sizeof(a));
	printf("%d\\n", sizeof(a + 0));
	printf("%d\\n", sizeof(*a));
	printf("%d\\n", sizeof(a + 1));
	printf("%d\\n", sizeof(a[1]));

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

解析:
在这里插入图片描述

int main()
{
	int a[] = { 1,2,3,4 };
	printf("%d\\n", sizeof(a));
	//4*4=16  sizeof(数组名),数组名表示整个数组,大小为4*4=16个字节
	printf("%d\\n", sizeof(a + 0));
	//4/8 a + 0 是第一个元素的地址,sizeof(a + 0)计算的是地址的大小
	printf("%d\\n", sizeof(*a));
	//4  *a是数组的第一个元素,sizeof(*a)计算的是第一个元素的大小
	printf("%d\\n", sizeof(a + 1));
	//4/8 a + 1是第二个元素的地址,sizeof(a+1)计算的地址的大小
	printf("%d\\n", sizeof(a[1]));
	//4 - 计算的是第二个元素的大小

	printf("%d\\n", sizeof(&a)); 
	//4/8 - &a虽然数组的地址,但是也是地址,sizeof(&a)计算的是一个地址的大小
	printf("%d\\n", sizeof(* &a));
	//16 - &a是取出数组地址,*&a是对数组地址解引用,得到是数组,sizeof是计算的数组的大小
	printf("%d\\n", sizeof(&a + 1));
	//4/8 - &a + 1 是跳过这个数组,sizeof是计算数组后面的空间的地址
	printf("%d\\n", sizeof(&a[0]));
	//4/8 - &a[0]是数组首元素地址
	printf("%d\\n", sizeof(&a[0] + 1));
	//4/8 - &a[0] + 1是数组第二个元素地址
}

字符数组

练习1

int main()
{
	char arr[] = { 'a','b','c','d','e','f' };
	printf("%d\\n", sizeof(arr));
	printf("%d\\n", sizeof(arr + 0));
	printf("%d\\n", sizeof(*arr));
	printf("%d\\n", sizeof(arr[1]));
	printf("%d\\n", sizeof(&arr));
	printf("%d\\n", sizeof(&arr + 1));
	printf("%d\\n", sizeof(&arr[0] + 1));
	
	printf("%d\\n", strlen(arr));
	printf("%d\\n", strlen(arr + 0));
	printf("%d\\n", strlen(*arr));
	printf("%d\\n", strlen(arr[1]));
	printf("%d\\n", strlen(&arr));
	printf("%d\\n", strlen(&arr + 1));
	printf("%d\\n", strlen(&arr[0] + 1));
}

解析:

int main()
{
	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是第一个元素,类型是char,char大小是1个字节
	printf("%d\\n", sizeof(arr[1]));
	//1  arr[1]表示第二个元素,类型是char,char大小是1个字节
	printf("%d\\n", sizeof(&arr));
	//4/8  &arr表示取出数组的地址,地址大小是4/8个字节
	printf("%d\\n", sizeof(&arr + 1));
	//4/8  &arr + 1表示跳过这个数组取后面一个元素的地址,地址大小是4/8个字节
	printf("%d\\n", sizeof(&arr[0] + 1));
	//4/8  &arr[0]+1表示第二个元素的地址,地址大小是4/8个字节

	printf("%d\\n", strlen(arr));
	//随机值  arr数组没有'\\0',但是strlen函数计算长度时,遇到'\\0'才会停止,所以输出为随机值
	printf("%d\\n", strlen(arr + 0));
	//随机值  同上文
	printf("%d\\n", strlen(*arr));
	//err strlen后面需要传递一个地址,*arr表示首元素,首元素是字符'a',其ASCII码是97,strlen会将97当作地址来处理
	//此时会造成越界访问,运行时会报错
	printf("%d\\n", strlen(arr[1]));
	//err  同上文
	printf("%d\\n", strlen(&arr));
	//随机值  &arr表示数组的地址,数组中没有\\0,所以用strlen计算长度的时候不知道会在哪里停止,所以是随机值
	printf("%d\\n", strlen(&arr + 1));
	//随机值  &arr + 1是跳过该数组取其后面的地址,同样不知道'\\0'在哪
	printf("%d\\n", strlen(&arr[0] + 1));
	//随机值  &arr[0] + 1表示第二个元素的地址,同样不知道'\\0'在哪
}

练习2

int main()
{
	char arr[] = "abcdef";
	printf("%d\\n", sizeof(arr));
	printf("%d\\n", sizeof(arr + 0));
	printf("%d\\n", sizeof(*arr));
	printf("%d\\n", sizeof(arr[1]));
	printf("%d\\n", sizeof(&arr));
	printf("%d\\n", sizeof(&arr + 1));
	printf("%d\\n", sizeof(&arr[0] + 1));

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

解析

int main()
{
	char arr[] = "abcdef";
	//"abcdef"表示a b c d e f \\0
	printf("%d\\n", sizeof(arr));
	//7  sizeof(arr)求数组的长度是 1*7=7个字节
	printf("%d\\n", sizeof(arr + 0));
	//4/8  这里sizeof计算的是数组首地址
	printf("%d\\n", sizeof(*arr));
	//1  sizeof计算的是数组首元素的大小
	printf("%d\\n", sizeof(arr[1]));
	//1  sizeof计算的是数组第二个元素的大小
	printf("%d\\n", sizeof(&arr));
	//4/8  sizeof计算的是数组的地址
	printf("%d\\n", sizeof(&arr + 1));
	//4/8  &arr + 1表示跳过整个数组下一位的地址。
	printf("%d\\n", sizeof(&arr[0] + 1));
	//4/8  &arr[0] + 1表示数组第二个元素的地址
	
	printf("%d\\n", strlen(arr));
	//6  strlen在计算字符串长度的时候,'\\0'不计算到长度中
	printf("%d\\n", strlen(arr + 0));
	//6  arr + 0表示首元素地址,与'\\0'差6个字符,所以strlen计算长度为6
	printf("%d\\n", strlen(*arr));
	//err  strlen后面需要传递一个地址,*arr表示首元素,首元素是字符'a',其ASCII码是97,
	//strlen会将97当作地址来处理此时会造成越界访问,运行时会报错
	printf("%d\\n", strlen(arr[1]));
	//err  strlen后面需要传递一个地址,arr[1]表示第二个元素'b',其ASCII码是98,
	//strlen会将97当作地址来处理此时会造成越界访问,运行时会报错
	printf("%d\\n", strlen(&arr));
	//6  &arr取的是首元素地址,与'\\0'差6个字符,所以strlen计算长度为6
	printf("%d\\n", strlen(&arr + 1));
	//随机值  &arr+1是跳过这个数组,取下一位地址,strlen计算的是从该地址到'\\0'
	printf("%d\\n", strlen(&arr[0] + 1));
	//5  &arr[0] + 1表示的是第二个元素的地址,与'\\0'差5个字符,所以strlen计算长度为5
} 

练习3

int main()
{
	char* p = "abcdef";
	printf("%d\\n", sizeof(p));
	printf("%d\\n", sizeof(p + 1));
	printf("%d\\n", sizeof(*p));
	printf("%d\\n", sizeof(p[0]));
	printf("%d\\n", sizeof(&p));
	printf("%d\\n", sizeof(&p + 1));
	printf("%d\\n", sizeof(&p[0] + 1));

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

解答

int main()
{
	char* p = "abcdef";
	printf("%d\\n", sizeof(p));
	//4/8  指针变量p存放的不是常量字符串"abcdef"本身,而是存放其首元素的地址
	printf("%d\\n", sizeof(p + 1));
	//4/8  p+1表示第二个元素的地址
	printf("%d\\n", sizeof(*p));
	//1  *p表示字符'a',类型是char,大小为1个字节
	printf("%d\\n", sizeof(p[0]));
	//1  p[0]表示的是首元素'a',类型是char,大小为1个字节
	printf("%d\\n", sizeof(&p));
	//4/8  &p表示取出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] + 1表示第二个元素的地址,地址大小为4/8

	printf("%d\\n", strlen(p));
	//6   p表示首元素地址,与'\\0'差6个字符,所以strlen计算长度为6
	printf("%d\\n", strlen(p + 1));
	//5  p+1表示第二个元素的地址,与'\\0'差5个字符,所以strlen计算长度为5
	printf("%d\\n", strlen(*p));
	//err  strlen后面需要传递一个地址,*p表示首元素,首元素是字符'a',其ASCII码是97,
	//strlen会将97当作地址来处理此时会造成越界访问,运行时会报错
	printf("%d\\n", strlen(p[0]));
	//err  strlen后面需要传递一个地址,arr[1]表示第二个元素'b',其ASCII码是98,
	//strlen会将97当作地址来处理此时会造成越界访问,运行时会报错
	printf("%d\\n", strlen(&p));
	//随机值  取出p的地址,传给strlen,strlen在往后寻找'\\0',不知道什么时候遇到'\\0'
	printf("%d\\n", strlen(&p + 1));
	//随机值  取出&p + 1的地址,传给strlen,strlen在往后寻找'\\0',不知道什么时候遇到'\\0'
	printf("%d\\n", strlen(&p[0] + 1));
	//5  &p[0] + 1表示的是第二个元素的地址,与'\\0'差5个字符,所以strlen计算长度为5
}

二维数组

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

	printf("%d\\n", sizeof(a));
	printf("%d\\n", sizeof(a[0][0]));
	printf("%d\\n", sizeof(a[0]));
	printf("%d\\n", sizeof(a[0] + 1));
	printf以上是关于征服指针——指针和数组练习的主要内容,如果未能解决你的问题,请参考以下文章

详解C语言指针我真的让C指针给我唱征服了~乌拉

指针练习:输出Hello

EDUCoder编程练习题解(指针一)

EDUCoder编程练习题解(指针一)

EDUCoder编程练习题解(指针一)

C语言进阶学习笔记二指针的进阶(重点必看+代码演示+练习)