数组和指针会了吗?进来做题!(未完待续)

一维数组

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])); // *(a+1)
	printf("%d\n", sizeof(&a));//整个数组的地址
	printf("%d\n", sizeof(*&a));//对数组的地址解引用
	printf("%d\n", sizeof(&a + 1));//数组的地址 +1  指向下一个整型数组
	printf("%d\n", sizeof(&a[0]));//第一个元素的地址
	printf("%d\n", sizeof(&a[0] + 1));//第二个元素的地址

在这里插入图片描述

核心知识点

1.只有单独出现a 的时候,a 猜代表整个数组。 a 出现在表达式中,都只是代表首元素的地址
2.对整个整型数组的地址解引用,得到的是整个整型数组。(对整型指针解引用得到的是一个整型,整型数组指针的type 是整型数组)
3.sizeof(&a + 1) 数组的地址 其实是 数组指针类型。 对指针+1,是+所指向的类型的大小。(&a + 1)代表的是下一个数组的地址,还是地址,只要是地址在32位下是 4 字节。

字符数组

用数组存放字符

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));//第二个元素的地址

在这里插入图片描述

核心知识点

1.char arr[] = { ‘a’, ‘b’, ‘c’, ‘d’, ‘e’, ‘f’ }; 类似这样的写法,是没有\0的
2.补充涉及到的一个整型提升

printf("%d\n", sizeof(*arr + 0));//整型提升4
printf("%d\n", sizeof(*arr));//1

(*arr + 0) *arr 对首元素的地址解引用 是首元素 字节大小为 1 但是后面加上的是一个整型 0 即为 char+int 整型提升 为int 对int 求sizeof 所以为 4.

char arr[] = { 'a', 'b', 'c', 'd', 'e', 'f' };
	//size_t strlen(const char * str);
	
	printf("%d\n", strlen(arr));//随机值
	printf("%d\n", strlen(arr + 0));//同上

	printf("%d\n", strlen(*arr)); //传参不对,解释要点1
	printf("%d\n", strlen(arr[1]));//同上

	printf("%d\n", strlen(&arr));//解释要点4 
	printf("%d\n", strlen(&arr + 1)); //比第一个随机值少一个char arr[] 少 6
	printf("%d\n", strlen(&arr[0] + 1)); //比第一个随机值少1

在这里插入图片描述

核心知识点

1.size_t strlen(const char * str);
strlen 是一个函数,它要接受的参数类型必须是一个指针。
当传参的类型不匹配时,编译器会出现报错或者运行时错误
2.strlen 从它接受的指针开始进行解引用看看内容是否时\0 。直到遇到\0停止。

字符’0’:char c = ‘0’; 它的ASCII码实际上是48。内存中存放表示:00110000

字符’\0’ :ASCII码为0,表示一个字符串结束的标志。这是转义字符(整体视为一个字符)。由于内存中存储字符,依然是存储的是对应字符集的字符编码;所以内存中的表现形式为0000 0000

整数0 :内存中表示为:0000 0000 0000 0000 0000 0000 0000 0000;虽然都是0,但是跟上面字符’\0’存储占用长度是不一样的;
3.char arr[] = { ‘a’, ‘b’, ‘c’, ‘d’, ‘e’, ‘f’ }; 没有 \0,因此求字符串长度会出现随即在。
4. 首元素地址和数组地址数值是一样的 有些编译器是可以使用的
数组指针 的类型时 char ()[6] 形参的类型时 char
不同编译器处理情况不太相同 有的时告警 说是类型不匹配。 设计到隐式转换,函数内部其实用到的还是char* 。
5.

 char arr[] = "abcdef"; 
 printf("%d\n", sizeof(arr)); 

内部有\0 sizeof§ 变成7
请注意区分在字符数组的初始化方式 char arr[] = “abcdef”; 和char arr[] = { ‘a’, ‘b’, ‘c’, ‘d’, ‘e’, ‘f’ };的本质区别

用指针指向字符

const char *p = "abcdef"; 
	printf("%d\n", sizeof(p)); // a 的地址
	printf("%d\n", sizeof(p + 1));//b 的地址
	printf("%d\n", sizeof(*p));//a
	printf("%d\n", sizeof(p[0])); //a
	printf("%d\n", sizeof(&p)); //p 的地址 二级指针
	printf("%d\n", sizeof(&p + 1)); ///p 的地址+1 还是 char *
	printf("%d\n", sizeof(&p[0] + 1)); //b 的地址

在这里插入图片描述
const char *p = “abcdef”; 字符串是在常量池里面的。
sizeof§ p的内容是a 的地址

	char *p = "abcdef"; 
    printf("%d\n", strlen(p)); //a 的地址
	printf("%d\n", strlen(p + 1));//b 的地址

	printf("%d\n", strlen(*p));//char a 错误
	printf("%d\n", strlen(p[0])); //char a 错误

	printf("%d\n", strlen(&p));//char **  是地址可以接受,但是不同编译器有的能编过去有的不行
	printf("%d\n", strlen(&p + 1)); //char **
	printf("%d\n", strlen(&p[0] + 1));//b 的地址

解释一下:
printf("%d\n", strlen(&p));
在这里插入图片描述
把 p 的地址传过去,因此会对p 的内容开始依次检查。也就是检查 58 58 a3 00 看里面什么时候出现\0 .
p 的内容是a 的地址,所以根本就没有到"abcdef"; 。

在此处加以补充说明的一点就是
关于字符串打印的方式略有不同

const char *a = "hello,world";
printf("%s\n", a);

a 里面虽然放的是字符串的首地址也就是h的首地址,但是通过a 仍然可以把字符串打出来。

二维数组

int a[3][4] = { 0 }; 

	printf("%d\n", sizeof(a)); //整个数组   --48
	
	printf("%d\n", sizeof(a[0][0])); //第一个元素的第一个整型 --4
	printf("%d\n", sizeof(a[0])); //第一个元素 是一个一维数组 --16
	
	
	printf("%d\n", sizeof(a[0] + 1)); // int *指向第一个元素的第二个整型  --指针 4
	//a[0] 看成一个数组名 对数组名+1 的意思是第二个元素的地址,此处就是指向第一个元素的第二个整型  
	printf("%d\n", sizeof(*(a[0] + 1))); // int 第一个元素的第二个整型 --4

	printf("%d\n", sizeof(*a));// 首元素 第一个一维数组  --16
	printf("%d\n", sizeof(*a + 1));//  指向第一个一维数组的第二个整型  --4
    printf("%d\n", sizeof(*(*a + 1)));//第一个一维数组的第二个整型 --4

	
	printf("%d\n", sizeof(a + 1)); // int (*)[4]+1  指向第二个元素 是一个一维数组 --指针 4
	printf("%d\n", sizeof(*(a + 1))); //第二个元素 是一个一维数组 --16

	printf("%d\n", sizeof(&a[0] + 1)); // int(*)[4] +1指向第二个元素( 是一个一维数组 )--指针4
	printf("%d\n", sizeof(*(&a[0] + 1)));//第二个元素--16


	printf("%d\n", sizeof(a[3]));//第三个一维数组,虽然数组出界了,但是对于出界数组来说可以读取访问不能存。--16

核心知识点

1.归纳
a+1 和&a[0]+1 的含义是一样的 都是指向第二个元素
a[0]+1 和 *a+1含义是一样的 表示第一个元素里面的第二个整型
在这里插入图片描述
2.对于出界的数组可以访问读取就是不能存储。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值