指针和数组习题

这篇博客详细探讨了C语言中数组与指针之间的关系,以及sizeof和strlen两个操作符的区别。通过实例展示了如何使用sizeof计算数组和指针的大小,以及strlen函数如何计算字符串长度。博客还涵盖了二维数组和结构体指针的用法,以及一些指针运算的习题,帮助读者深入理解C语言的基础概念。
摘要由CSDN通过智能技术生成

数组名的意义

1.sizeof(数组名),这里的数组名表示整个数组,计算的是整个数组的大小
2.&数组名,这里的数组名表示整个数组,取出的是整个数组的地址
3.除此之外所有的数组名都表示首元素的地址

一维数组

#include<stdio.h>
int main()
{
	//一维数组
	int a[] = { 1,2,3,4 };
	printf("%d\n", sizeof(a));//4*4=16
	printf("%d\n", sizeof(a+0));//4/8	a+0是数组第一个元素的地址,是地址就是4/8个字节
	printf("%d\n", sizeof(*a));//4	首元素地址解引用,就是第一个元素大小4
	printf("%d\n", sizeof(a+1));//4/8	第二个元素地址大小
	printf("%d\n", sizeof(a[1]));//4	第二个元素的大小
	printf("%d\n", sizeof(&a));//4/8	&a取出的是数组的地址,是地址就是4/8
	printf("%d\n", sizeof(*&a));//16	计算的是整个数组的大小
	printf("%d\n", sizeof(&a+1));//4/8	&a是整个数组的地址,+1跳过整个数组,地址还是4/8
	printf("%d\n", sizeof(&a[0]));//4/8		第一个元素的地址
	printf("%d\n", sizeof(&a[0]+1));//4/8	第二个元素的地址
	return 0;
}

总结是地址就是4/8,是个数就另外看。
*&a相当于a,表示这整个数组

字符数组

#include<stdio.h>
#include<string.h>
int main()
{
	char arr[] = { 'a','b','c','d','e','f' };
	printf("%d\n", sizeof(arr));//6
	printf("%d\n", sizeof(arr+0));//4/8		数组首元素地址
	printf("%d\n", sizeof(*arr));//1		*arr是首元素,首元素是一个字符,大小是一个字节
	printf("%d\n", sizeof(arr[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	第二个元素的地址


	printf("%d\n", strlen(arr));//随机值	arr数组中没有\0,所以strlen函数会继续往后找\0,统计\0之前出现的字符个数
	printf("%d\n", strlen(arr+0));//随机值	arr+0是数组首元素地址
	//printf("%d\n", strlen(*arr));//err	*arr是数组首元素,'a'-97,strlen函数非法访问
	//printf("%d\n", strlen(arr[1]));//err	'b'-98,非法访问
	printf("%d\n", strlen(&arr));//随机值	数组的地址
	printf("%d\n", strlen(&arr+1));//随机值	跳过整个数组后的地址
	printf("%d\n", strlen(&arr[0]+1));//随机值	第二个元素的地址

	return 0;
}

总结:

sizeof是一个操作符
sizeof计算的是对象所占内存的大小,单位是字节
不管内存中存放的是什么,只在乎内存大小

strlen 是一个库函数
求字符串长度,从给定的地址向后访问字符,统计\0之前出现的字符个数

#include<stdio.h>
#include<string.h>
int main()
{
	char arr[] = "abcdef";
	printf("%d\n", sizeof(arr));//7		
	printf("%d\n", sizeof(arr+0));//4/8
	printf("%d\n", sizeof(*arr));//1
	printf("%d\n", sizeof(arr[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

	printf("%d\n", strlen(arr));//6
	printf("%d\n", strlen(arr+0));//6
	//printf("%d\n", strlen(*arr));//err
	//printf("%d\n", strlen(arr[1]));//err
	printf("%d\n", strlen(&arr));//6
	printf("%d\n", strlen(&arr+1));//随机值
	printf("%d\n", strlen(&arr[0]+1));//5

	return 0;
}
#include<stdio.h>
#include<string.h>
int main()
{
	char *p = "abcdef";
	printf("%d\n", sizeof(p));//4/8		p是指针变量,计算的是指针变量的大小
	printf("%d\n", sizeof(p+1));//4/8	b的地址
	printf("%d\n", sizeof(*p));//1		*p是元素a
	printf("%d\n", sizeof(p[0]));//1	p[0]->*(p+0)->*p,首元素
	printf("%d\n", sizeof(&p));//4/8	p在内存中的地址
	printf("%d\n", sizeof(&p + 1));//4/8	&p+1是跳过p之后的地址
	printf("%d\n", sizeof(&p[0] + 1));//4/8		b的地址

	printf("%d\n", strlen(p));//6
	printf("%d\n", strlen(p + 1));//5	从b 的位置开始向后数字符
	//printf("%d\n", strlen(*p));//err
	//printf("%d\n", strlen(p[0]));//err
	printf("%d\n", strlen(&p));//随机值
	printf("%d\n", strlen(&p + 1));//随机值
	printf("%d\n", strlen(&p[0] + 1));//5


	return 0;
}

二维数组

元素首地址是第一行地址

#include<stdio.h>
int main()
{
	int a[3][4] = { 0 };
	printf("%d\n", sizeof(a));//48		计算的是整个数组的大小,单位是字节3*4*4=48
	printf("%d\n", sizeof(a[0][0]));//4		第一行第一个元素的大小
	printf("%d\n", sizeof(a[0]));//16		第一行的大小
	printf("%d\n", sizeof(a[0]+1));//4/8	第一行第二个元素地址
	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			第一行元素大小
	printf("%d\n", sizeof(a[3]));//16		int[]4

	return 0;
}

指针习题

1.a是首元素地址加1,第二个元素地址解引用就是2
&a+1是跳过整个数组,指向5后面,强制类型转换为int*

#include<stdio.h>
int main()
{
	int a[5] = { 1,2,3,4,5 };
	int* ptr = (int*)(&a + 1);
	printf("%d,%d", *(a + 1), *(ptr - 1));//2,5
	return 0;
}

#include<stdio.h>
//结构体Test类型的变量大小是20个字节
struct Test
{
	int Num;
	char* pcName;
	short sDate;
	char cha[2];
	short sBa[4];
}*p;
int main()
{
	p = (struct Test*)0x100000;

	//%p 打印的是地址,打印32位比特位,但是用的是16进制展示的
	//00000000 00000000 00000000 00000000 二进制
	//00		00		00			00		十六进制
	printf("%p\n", p + 0x1);//00100014		p是结构体指针,相加就是结构体指针大小
	printf("%p\n", (unsigned long)p + 0x1);//00100001  强转成长整型,相加就是整型相加
	printf("%p\n", (unsigned int*)p + 0x1);//00100004	整型指针+1,就是加4

	return 0;
}
#include<stdio.h>
int main()
{
	int a[4] = { 1,2,3,4 };
	int* ptr1 = (int*)(&a + 1);//
	int* ptr2 = (int*)((int)a + 1);//
	printf("%x,%x", ptr1[-1], *ptr2);//%x 打印的是有效位数字 4,2000000
	//ptr1[-1]=*(ptr1-1),int*(&a+1)指向的是4后面的一位
	//
	return 0;
}
#include<stdio.h>
int main()
{
	int a[3][2] = { (0,1),(2,3),(4,5) };//()里面是逗号表达式,将()改成{}就不是逗号表达式了
	int* p;
	p = a[0];
	printf("%d", p[0]);//p[0]=*(p+0);

	return 0;
}
#include<stdio.h>
int main()
{
	int a[5][5];
	int(*p)[4];//指针数组
	p = a;//p指向的是a的首元素地址
	printf("%p,%d\n", &p[4][2] - &a[4][2] ,&p[4][2]- &a[4][2]);
//p[4][2]=*(*(p+4)+2)
	return 0;
}

在这里插入图片描述

#include<stdio.h>
int main()
{
	int aa[2][5] = { 1,2,3,4,5,6,7,8,9,10 };
	int* ptr1 = (int *)(&aa + 1);
	int* ptr2 = (int *)(*(aa + 1));
	printf("%d,%d", *(ptr1 - 1), *(ptr2 - 1));//10,5

	return 0;
}
#include<stdio.h>
int main()
{
	char* a[] = { "work","at","alibaba" };
	char** pa = a;
	pa++;
	printf("%s\n", *pa);

	return 0;
}

字符指针数组存的实际上是字符串首元素地址
二级指针pa指向a首元素地址,pa++跳过一个字节指向字符a,打印%s,将整个at 打印出

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值