【指针及数组的相关题目】

小朋友你是否有很多问号,为什么别人在那看漫画...................................................................

目录

前言

一、【sizeof和strlen之间的区别】

二、【数组相关题目】

三、【指针相关题目】

总结


前言

经过指针和数组的学习,现在做一些,强化练习。


一、【sizeof和strlen之间的区别】

在正式开始今天的内容之前,首先说一下sizeof和strlen之间的区别于联系:

【sizeof】

首先我们都知道,sizeof是一种操作符,是用来求变量所占空间大小的,其单位是字节。它的返回值类型是size_t。

【strlen】

strlen则是一种库函数,用来求字符串的长度,求的是‘\0’之前的字符个数,返回值是字符串的长度。使用时包含头文件<string.h>

【区别与联系】

按理说,sizeof和strlen之间并没有什么本质上的联系,但是他们之间却有很大区别:

1.sizeof是一种操作符,计算的是占用空间的大小,单位是字节,不关注内存中到底存放的是什么。

2.strlen是一种库函数,是针对字符串的求的是字符串的长度,,本质上统计的是,'\0'之前出现的字符个数。

当我们遇到“\0"时我们就要停止读取,此时“\0"前字符的个数就是字符串的长度,注意:这里的“\0"只是结束标志,仅仅告诉我们strlen函数读取到这里就要停止了,“\0"不算做一个字符!!!

代码举例:

常见数据类型

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h> 
#include <string.h>    

int main()
{
    //字符串数组方式  
    int a1;
    int b1;
    char str1[11] = "0123456789";//字符串数组定义时注意为字符串个数+1  
    a1 = sizeof(str1);//a1=11,统计到字符串结束符’\0’为止  
    b1 = strlen(str1);//b1=10,统计到字符串结束符之前  
    printf("a1 = % d, b1 = % d\n", a1, b1);

    //字符串指针方式  

    int a2;
    int b2;
    int c2;
    char* str2 = "0123456789";
    a2 = sizeof(str2);//a2=4;str为指向字符串常量的字符串指针  
    b2 = strlen(str2);//b2=10;  
    c2 = sizeof(*str2);//c2=1;*str2表示第一个字符  
    printf("a2 = % d, b2 = % d, c2 = % d\n", a2, b2, c2);

    //未定义字符串大小方法  
    int a3;
    int b3;
    char str3[] = "0123456789";
    a3 = sizeof(str3);//a3=11;  
    b3 = strlen(str3);//b3=10;  
    printf("a3 = % d, b3 = % d\n", a3, b3);

    //整型数组,strlen只能用于字符串  
    int a4;
    int a[] = { 1,2,3,4,5,6,7,8,9,0 };
    a4 = sizeof(a);//a4=字符个数*字节数  
    printf("a4 = % d\n", a4);
    return 0;
}

指针变量

void fun(int a[100])
{
    printf(" % d\n", sizeof(a));//结果为4,而非400  
}
void fun1(int* p)
{
    printf(" % d\n", sizeof(p));//结果为4  
}

int main()
{

    int a[10];
    int* b[10];
    int(*c)[10];
    int* p;
    int i[100];
    int* q = i;
    printf(" % d\n", sizeof(a));//40=4*10  
    printf(" % d\n", sizeof(b));//指针数组,装有10个指向整型变量的指针,本质上还是个数组,故其大小为10*4=40  
    printf(" % d\n", sizeof(c));//数组指针,大小为4  
    printf(" % d\n", sizeof(p));//指针大小,不管什么类型的指针,都占4个字节大小  
    fun(i);//4 不是400  
    fun(q);//4 不是400  
    return 0;
}

二、【数组相关题目】

数组和指针  
数组 - 能够存放一组相同类型的元素,数组的大小取决于数组的元素个数和元素类型  
指针 - 地址/指针变量 ,大小是4/8个字节  
数组是数组,指针是指针,二者不等价  
数组名是数组首元素的地址,这个地址就可以存放在指针变量中 ,我们就可以使用指针来遍历数组。  
 
数组名大部分情况下数组名是数组首元素的地址 ,但是有2个例外:  
  //sizeof(数组名) - 数组名表示整个数组,计算的是整个数组的大小  
  //&数组名 - 数组名表示整个数组,取出的是数组的地址 
1.一维数组
//题目
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));//16
	//sizeof(a)就是数组名单独放在sizeof内部,计算的数组总大小,单位是字节
	printf("%d\n", sizeof(a + 0));//4/8 个字节
	//a+0 其实是数组首元素的地址,因为a此时并没有单独放到sizeof内部,a表示数组首元素的地址。
	printf("%d\n", sizeof(*a));//4
	//a是数组首元素的地址 - &a[0]
	//*a -> *&a[0] -> a[0]
	printf("%d\n", sizeof(a + 1));//4/8
	//a是数组首元素的地址 -- int*
	//a+1 跳过1个整型, 是第二个元素的地址
	//
	printf("%d\n", sizeof(a[1]));//4
	printf("%d\n", sizeof(&a));//4/8
	//&a - 取出的是数组的地址,但是数组的地址也是地址呀,是地址大小就是4/8字节
	//int (*pa)[4] = &a;//int(*)[4]
	//
	printf("%d\n", sizeof(*&a));//16
	//sizeof(a)
	//int(*)[4]
	//
	printf("%d\n", sizeof(&a + 1));//4/8
	//&a -->  int (*)[4]
	//&a+1 跳过一个数组

	printf("%d\n", sizeof(&a[0]));//取出首元素的地址 4/8
	printf("%d\n", sizeof(&a[0] + 1));//第二个元素的地址

	return 0;
}

2.字符数组

//题目
int main()
{
    //1.
	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));
    //2.
	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));
    //3.
	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));
	return 0;
}

解析:

//1.
int main()
{
	//字符数组
	char arr[] = { 'a','b','c','d','e','f' };//这是字符数组,不是字符串与“abcdef”不同arr里没有放置'\0'
	//strlen
	printf("%d\n", strlen(arr));//随机值,因为不知道\0的位置
	printf("%d\n", strlen(arr + 0));//随机值
	printf("%d\n", strlen(*arr));//非法访问
	printf("%d\n", strlen(arr[1]));//'b' - 98 当成地址,形参非法访问
	printf("%d\n", strlen(&arr));//随机值
	printf("%d\n", strlen(&arr + 1));//随机值-6
	printf("%d\n", strlen(&arr[0] + 1));//随机值-1
 
	//sizeof
	printf("%d\n", sizeof(arr));//6
	printf("%d\n", sizeof(arr + 0));//arr+0是数组首元素的地址 4/8
	printf("%d\n", sizeof(*arr));//*arr是首元素的,计算的是首元素的大小 1
	printf("%d\n", sizeof(arr[1]));//1
	printf("%d\n", sizeof(&arr));//&arr是数组的地址 4/8
	printf("%d\n", sizeof(&arr + 1));//&arr + 1跳过一个数组后的地址,4/8
	printf("%d\n", sizeof(&arr[0] + 1));//4/8 第二个元素的地址


	return 0;
}
//2.
int main()
{   

	char arr[] = "abcdef";//[a b c d e f \0]
    //printf("%d\n", sizeof(arr));//7
	//printf("%d\n", sizeof(arr + 0));//4/8
	//printf("%d\n", sizeof(*arr));//*arr -是数组首元素 1
	arr[0]   *(arr+0)
	int sz = sizeof(arr)/sizeof(*arr);
	int sz = sizeof(arr)/sizeof(arr[0]);

	//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
	//&arr - char (*)[7]
	printf("%d\n", strlen(&arr + 1));//随机值
	printf("%d\n", strlen(&arr[0] + 1));//5

	return 0;
}
//3.
int main()
{
	char* p = "abcdef";//p中存放的是字符串首字符a的地址。
    //printf("%d\n", sizeof(p));//4 / 8
	//printf("%d\n", sizeof(p + 1));//'b'的地址,4/8
	//printf("%d\n", sizeof(*p));//1
	//printf("%d\n", sizeof(p[0]));//*(p+0)--'a' 1
	//printf("%d\n", sizeof(&p));//4/8
	//printf("%d\n", sizeof(&p + 1));4/8
	//printf("%d\n", sizeof(&p[0] + 1));//&p[0]+1是'b'的地址


	//printf("%d\n", strlen(p));//6
	//printf("%d\n", strlen(p + 1));//p+1是'b'的地址 5
	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));同//printf("%d\n", strlen(p + 1));


	
	return 0;
}

3.二维数组

题目:

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("%d\n",sizeof(*(a[0]+1)));
printf("%d\n",sizeof(a+1));
printf("%d\n",sizeof(*(a+1)));
printf("%d\n",sizeof(&a[0]+1));
printf("%d\n",sizeof(*(&a[0]+1)));
printf("%d\n",sizeof(*a));
printf("%d\n",sizeof(a[3]));

解析:

int main()
{
	int a[3][4] = { 1,2,3,4,5,6,7,8,9,10,11,12 };

	printf("%d\n", sizeof(a));//48 - a这个二维数组的数组名单独放在sizeof内部,计算整个数组的大小
	printf("%d\n", sizeof(a[0][0]));//第一行第一个元素,4个字节
	printf("%d\n", sizeof(a[0]));//16
	//a[0] 第一行的数组名,这时数组名单独放在sizeof内部了
	//计算的是数组的大小,单位是字节,16
	printf("%d\n", sizeof(a[0] + 1));//4
	//a[0]不是单独放在sizeof内部,a[0]表示的首元素的地址,即第一行第一个元素的地址 - &a[0][0]
	//a[0] + 1 是第一行第2个元素的地址 &a[0][1]
	printf("%d\n", sizeof(*(a[0] + 1)));//a[0][1] 大小是:4个字节
	printf("%d\n", sizeof(a + 1));//
	//a作为二维数组的数组名并非单独放在sizeof内部,所以表示首元素的地址
	//二维数组的首元素是第一行,这里的a就是第一行的地址---  int (*)[4]
	//a+1是跳过第一行,指向了第二行

	printf("%d\n", sizeof(*(a + 1)));//16
	//*(a+1)-->a[1]
	printf("%d\n", sizeof(&a[0] + 1));//4/8
	//&a[0]是第一行的地址
	//&a[0]+1是第二行的地址
	printf("%d\n", sizeof(*(&a[0] + 1)));//16  a[1]
	printf("%d\n", sizeof(*a));//16 *a - 就是第一行
	//*a -- *(a+0) -- a[0]
	printf("%d\n", sizeof(a[3]));//16
	return 0;
}

注:sizeof中的表达式并不会真正计算,因为sizeof只关注所占空间的大小。

举例:

int main()
{
	int a = 5;
	short s = 11;
	printf("%d\n", sizeof(s = a + 2));//2
	printf("%d\n", s);//11
	return 0;
}

这里a为5,按理说+2应该变为7,s应该被赋值为19可是:

总结:

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

三、【指针相关题目】

1.程序输出结果是什么?

int main()
{
  int a[5] = { 1, 2, 3, 4, 5 };
  int *ptr = (int *)(&a + 1);
  printf( "%d,%d", *(a + 1), *(ptr - 1));
  return 0;
}

解答:

2.程序执行结果:

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);
	return 0;
}

解答:

3.题目:

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

解答:

4.题目:

int main()
{
	int a[5][5];
	int(*p)[4];
	p = a;
	printf("%p,%d\n", &p[4][2] - &a[4][2], &p[4][2] - &a[4][2]);
	return 0;
}

解答:

5.题目:

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));
  return 0;
}

解答:

6.题目:

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

解答:

7.题目:

int main()
{
char *c[] = {"ENTER","NEW","POINT","FIRST"};
char**cp[] = {c+3,c+2,c+1,c};
char***cpp = cp;
printf("%s\n", **++cpp);
printf("%s\n", *--*++cpp+3);
printf("%s\n", *cpp[-2]+3);
printf("%s\n", cpp[-1][-1]+1);
return 0;
}

解答:


总结

这次的内容,到这就结束了,感谢观看!


..........................................................................................................天使的魔法,温暖中慈祥

                                                                                                         ————《听妈妈的话》

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值