c语言指针和数组笔试题解析-1

strlen()和sizeof()的区别

1.strlen函数:库函数,功能:求字符串的长度。

  • 函数原型:size_t strlen ( const char * str );
  • 格式:strlen (字符指针表达式)
  • 功能:计算给定字符串的(unsigned int型)长度,不包括'\0'在内
  • 说明返回s的长度,不包括结束符NULL。
  • 头文件:string.h
  • 运算时执行

2.sizeof:在 C 语言中,sizeof() 是一个判断数据类型或者表达式长度的运算符。

sizeof()是在编译阶段执行。

  • 返回值:返回内存所占的字节数。
  • 返回值类型unsigned int
  1. sizeof的两种类型:sizeof(类型) sizeof 对象
  2. sizeof对一个表达式求值,编译器根据表达式的最终结果类型来确定大小,一般不会对表达式进行计算。
  3. sizeof也可以对一个函数调用求值,其结果是函数返回类型的大小,函数并不会被调用。
#include<stdio.h>
int main()
{
	int i = 1;
	printf("%d\n", sizeof(i++));
	//Sizeof(i++)不执行i++,i++返回值类型是int,占有4个字节,结果4
	printf("%d\n", i);
	//不执行i++,只判断表达式的类型 结果1
	printf("%d\n", sizeof(3.13f + 9));
	//3.14f单精度浮点型 + 整形,发生整形提升结果是float类型,结果4
	printf("%d\n", sizeof(2));
	//	2是整形,结果4
	return 0;
}
#include<stdio.h>
char Fun( char arr[10])
{
	printf("%d\n", sizeof(arr));//4/8 数组作为函数参数,被退化成为了指针
}
int Fun1(char arr[])
{
	printf("%d\n", sizeof(arr));//4/8 数组作为函数参数,被退化成为了指针
}
int main()
{
	char arr[10];
	Fun(arr);
	Fun1(arr);
	printf("%d\n", sizeof(Fun(arr)));//sizeof(函数),但是不会调用函数,返回值类型char,结果1
	printf("%d", sizeof(Fun1(arr)));//sizeof(函数),但是不会调用函数,返回值类型int,结果4
	return 0;
}

 指针和数组面试题

1.整型数组

#include<Stdio.h>
int main()
{
int a[] = { 1,2,3,4 };
printf("%d\n", sizeof(a));//16 sizeof(数组名),得到数组所占内存空间大小,单位是字节。
printf("%d\n", sizeof(a + 0));// 4/8 数组名表示首元素地址,a+0表示a[0]的地址。
printf("%d\n", sizeof(*a));//4 a表示首元素地址,*a表示a[0],a[0]是int类型,相当于sizeof(int)
printf("%d\n", sizeof(a + 1));// 4/8 数组名表示首元素地址,a+1表示a[1]的地址。
printf("%d\n", sizeof(a[1]));//4 a[1]是int类型,相当于sizeof(int)
printf("%d\n", sizeof(&a));// 4/8 &a,得到了整个数组的地址,指针大小4/8
printf("%d\n", sizeof(*&a));// 16 &a,得到了整个数组的地址,解引用得到整个数组
printf("%d\n", sizeof(&a + 1));//4/8 &a,得到了整个数组的地址,对应类型 int(*)[],+1跳过了整个数组,得到的仍然是地址
printf("%d\n", sizeof(&a[0]));// 4 /8 得到a[0]的地址
printf("%d\n", sizeof(&a[0] + 1));//4/8 a[0]的地址+1得到a[1]的地址
return 0;
}

 2,字符数组

#include<stdio.h>
#include<string.h>
int main()
{
	char arr[] = { 'a','b','c','d','e','f' };//实际存放 a,b,c,d,e,f
	printf("%d\n", sizeof(arr));//6 sizeof(数组名)得到整个数组的大小
	printf("%d\n", sizeof(arr + 0));//4/8 arr表示首元素地址,arr+0表示首元素地址
	printf("%d\n", sizeof(*arr));// 1 arr表示首元素地址,解引用表示首元素arr[0],相当于sizeof(char)
	printf("%d\n", sizeof(arr[1]));//1 相当于sizeof(char)
	printf("%d\n", sizeof(&arr));//4/8 &arr,得到了整个数组的地址
	printf("%d\n", sizeof(&arr + 1));//4/8 &arr,得到了整个数组的地址,对应类型 char(*)[],+1跳过了整个数组,得到的仍然是地址
	printf("%d\n", sizeof(&arr[0] + 1));//4/8 得到了arr[1]的地址

	//strlen()求字符串长度,遇到\0停止
	printf("%d\n", strlen(arr));
	//随机值 实际存放a,b,c,d,e,f,由于arr没有\0,函数就会一直向后查找,直到遇到了\0为止,所以说返回随机值
	printf("%d\n", strlen(arr + 0));
	//随机值 arr表示首元素地址,arr+0也是arr[0]的地址,同上
	printf("%d\n", strlen(*arr));
	//此程序崩溃
	//arr表示首元素地址,*arr得到了arr[0],也就是字符'a'。
	//strlen的参数是字符指针,这里传入了字符'a',对应的ascii码值是97,把97当作了地址,
	//从97开始求字符串长度,但是97是野指针,造成了非法访问。
	printf("%d\n", strlen(arr[1]));//同上,将b对应的ascii码值98作为地址。
	printf("%d\n", strlen(&arr));
	// 随机值 取出了整个数组的地址,对应类型char(*)[],但是strlen的参数是(char*),发生强制类型转换,得到了arr[0]的地址,从此地址开始查找
	printf("%d\n", strlen(&arr + 1));
	//随机值 &arr,得到了整个数组的地址,对应类型 char(*)[],+1跳过了整个数组,得到的仍然是地址,从这个地址开始查找
	printf("%d\n", strlen(&arr[0] + 1));
	//随机值 得到了arr[1]的地址,从此地址开始查找
	return 0;
}
#include<stdio.h>
#include<string.h>
int main()
{
	char arr[] = "abcdef";//实际存放 a,b,c,d,e,f,\0
	printf("%d\n", sizeof(arr));// 7 sizeof(数组名),得到了数组的实际内存空间,以字节为单位。
	printf("%d\n", sizeof(arr + 0));// 4/8  arr表示首元素地址
	printf("%d\n", sizeof(*arr));//1 arr表示首元素地址,*arr表示arr[0],相当于sizeof(char)
	printf("%d\n", sizeof(arr[1]));//1 相当于sizeof(char)
	printf("%d\n", sizeof(&arr));//4/8 &arr得到数组地址,地址的大小4/8
	printf("%d\n", sizeof(&arr + 1));// 4/8 &arr得到数组地址,+1跳过了一个数组,得到了指针
	printf("%d\n", sizeof(&arr[0] + 1));//4/8 arr[1]的地址

	printf("%d\n", strlen(arr));// 6 从arr[0]开始求字符串长度,不包括\0
	printf("%d\n", strlen(arr + 0));//6 同上
	printf("%d\n", strlen(*arr));//程序崩溃*arr得到了字符'a',将字符'a'的ascii码值97作为地址 非法内存访问
	printf("%d\n", strlen(arr[1]));//程序崩溃 将字符'b'的ascii码值98作为地址 非法内存访问
	printf("%d\n", strlen(&arr));// 6 得到了整个数组的地址,char(*)[6]强制转化为char*,从arr[0]开始查找
	printf("%d\n", strlen(&arr + 1));//随机值 跨过了整个数组,但是得到的仍然是地址,从此开始查找,遇到\0停止
	printf("%d\n", strlen(&arr[0] + 1));// 5 从arr[1]的地址开始查找
	return 0;
}
#include<stdio.h>
#include<string.h>
int main()
{
	const char* p = "abcdef";
	printf("%d\n", sizeof(p));//4/8 sizeof(指针变量)
	printf("%d\n", sizeof(p + 1));// 4/8 p+1指向了b,sizeof(指针)
	printf("%d\n", sizeof(*p));//1 *p得到了字符a,sizeof(char)
	printf("%d\n", sizeof(p[0]));//1 p[0]是字符a,sizeof(char)
	printf("%d\n", sizeof(&p));// 4/8 &p,一级指针的地址,也就是二级指针。
	printf("%d\n", sizeof(&p + 1));//4/8 p是一级指针,&p二级指针,&p1指向p的末端,得到的仍然是指针
	printf("%d\n", sizeof(&p[0] + 1));//4/8 p[0]是’a',a的地址加1指向了字符'b'。

	printf("%d\n", strlen(p));// 6 p存放的是a的地址,从此地址开始求字符串长度,
	printf("%d\n", strlen(p + 1));//5 p+1指向了字符'b',从b开始求字符串长度。
	printf("%d\n", strlen(*p));//程序崩溃 *p得到字符'a',将对应ascii码值当作地址,非法内存访问
	printf("%d\n", strlen(p[0]));//程序崩溃 同上
	printf("%d\n", strlen(&p));//随机值,&p,一级指针的地址,在p的空间内计算字符串长度
	printf("%d\n", strlen(&p + 1));//随机值,在p的末端后面空间内计算字符串长度
	printf("%d\n", strlen(&p[0] + 1));//5 字符b的地址
	return 0;
}
#include<stdio.h>
int main()
{
	int a[3][4] = { 0 };
	printf("%d\n", sizeof(a));
	//48 sizeof(数组名)求整个数组所占的内存空间,单位是字节
	printf("%d\n", sizeof(a[0][0]));// 4 a[0][0]是0,sizeof(int)
	printf("%d\n", sizeof(a[0]));//16
	//a[0]是第一行的一维数组数组名,代表着一维数组首元素的地址
	//sizeof(数组名)求得数组的内存空间,所以说sizeof(a[0])得到的是a[0]这一维数组的内存16
	printf("%d\n", sizeof(a[0] + 1));//4/8
	//a[0]是第一行一维数组的数组名,也代表一维数组首元素地址,a[0]+1得到a[0][1]的地址
	printf("%d\n", sizeof(*(a[0] + 1)));// 4 得到a[0][1]的元素,sizeof(int) 
	printf("%d\n", sizeof(a + 1));//4/8 a代表第一行的地址,a+1得到了第二行的地址
	printf("%d\n", sizeof(*(a + 1)));// 16 得到了第二行
	printf("%d\n", sizeof(&a[0] + 1));//4/8
	//a[0]是第一行首元素的地址,也是第一行这一个一维数组的数组名
	//&a这里的a代表着数组名,&a[0]得到第一行的地址,+1得到第二行的地址,类型int(*)[];
	printf("%d\n", sizeof(*(&a[0] + 1)));
	//16 a[0]是第一行的数组名,&数组名得到第一行的地址,第一行地址加1得到第二行地址,解引用得到第二行
	printf("%d\n", sizeof(*a));//16 a代表第一行地址,得到第一行
	printf("%d\n", sizeof(a[3]));
	// 16 a[3]表示第四行的地址,也是一维数组的数组名,虽然越界,但是sizeof不会对内部表达式进行操作,不会崩溃
	//sizeof(数组名)得到第四行数组的内存空间。
	return 0;
}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值