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
- sizeof的两种类型:sizeof(类型) sizeof 对象
- sizeof对一个表达式求值,编译器根据表达式的最终结果类型来确定大小,一般不会对表达式进行计算。
- 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;
}
?
|