信息技术网站建设市场分析,都江堰建设局官方网站,陕西网站建设公司找哪家,网站运营推广策划书在讲解之前我们先回顾一下#xff0c;以下将要涉及的重要知识点#xff1a;
1、数组名是什么#xff1f; ①sizeof(数组名)#xff0c;这里的数组名表示整个数组#xff0c;计算的是整个数组的大小#xff0c;单位是字节#xff1b; ②数组名#xff0c;这里的数…在讲解之前我们先回顾一下以下将要涉及的重要知识点
1、数组名是什么 ①sizeof(数组名)这里的数组名表示整个数组计算的是整个数组的大小单位是字节 ②数组名这里的数组名表示整个数组取出的是整个数组的地址 ③除此之外所有的数组名都是数组首元素的地址。 2、sizeof ①sizeof是关键字(如变量名不能和关键字一样)也是操作符(功能:计算操作数的类型长度) ②sizeof的特点sizeof内部的表达式是不计算的 ③sizeof不是函数因为函数调用的时候要写括号但是sizeof后边的括号可以省略(注:变量名可以类型不可以)。 ④sizeof的计算结果是无符号的整形unsigned int。 3、strlen ①strlen是C语言提供的库函数可以计算字符串的长度统计的是\0之前的字符个数。 ②函数原型size_t strlen(const char *str)从中我们可知strlen的参数是一个地址返回类型是无符号的整形。 总结 ①除了两种特殊情况数组名单独放在sizeof()里和数组名其他情况数组名都表示数组的首元素地址。 ②sizeof作为操作符计算的是操作数的类型长度sizeof内部的表达式是不计算的。 ③strlen的形参是一个地址所以实参也要是地址。 接下来我们开始练习 一维数组
分析代码运行后的结果
1、整形数组
1sizeof——计算的是操作数的类型大小单位字节
#includestdio.hint main()
{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));return 0;
}答案分析
#includestdio.hint main()
{int a[] { 1,2,3,4 };printf(%d\n, sizeof(a));//16字节单独的数组名计算的是整个数组的大小printf(%d\n, sizeof(a 0));//4/8字节不是单独的数组名a0是首元素的地址printf(%d\n, sizeof(*a));//4字节*a相当于a[0]计算的是首元素的大小printf(%d\n, sizeof(a 1));//4/8字节不是单独的数组名a1是第二个元素的地址printf(%d\n, sizeof(a[1]));//4字节a[1]是第二个元素计算的是第二个元素的大小printf(%d\n, sizeof(a));//4/8字节数组名取的是整个数组的地址类型是数组指针int (*)[4]printf(%d\n, sizeof(*a));//16个字节数组名取出整个数组的地址解引用得到整个数组(*a--a)printf(%d\n, sizeof(a 1));//4/8字节,a1跳过整个数组还是数组指针(不管是否越界只操作数关注类型)printf(%d\n, sizeof(a[0]));//4/8字节a[0]取的是第一个元素的地址printf(%d\n, sizeof(a[0] 1));//4/8字节a[0]1是第二个元素的地址return 0;
}
2.字符数组
情景1 例如char arr[] {a,b,c,d,e,f}; 1sizeof——计算的是操作数的类型大小
#includestdio.hint main()
{char arr[] {a,b,c,d,e,f};printf(%d\n, sizeof(arr));printf(%d\n, sizeof(arr0));printf(%d\n, sizeof(*arr));printf(%d\n, sizeof(arr[1]));printf(%d\n, sizeof(arr));printf(%d\n, sizeof(arr1));printf(%d\n, sizeof(arr[0]1));return 0;
}
答案分析
#includestdio.hint main()
{char arr[] { a,b,c,d,e,f };printf(%d\n, sizeof(arr));//6字节数组名单独放在sizeof内部计算的是整个数组的大小printf(%d\n, sizeof(arr 0));//4/8字节数组名没有单独放arr0是数组首元素的地址printf(%d\n, sizeof(*arr));//1字节*arr相当于arr[0]是数组首元素计算的是首元素的大小printf(%d\n, sizeof(arr[1]));//1字节arr[1]是第二个元素计算的是第二个元素的大小printf(%d\n, sizeof(arr));//4/8字节数组名取出的整个数组的地址类型是数组指针char (*)[6]printf(%d\n, sizeof(arr 1));//4/8字节arr1向后跳过整个数组指向后面的空间地址但类型不变printf(%d\n, sizeof(arr[0] 1));//4/8字节arr[0]1是数组第二个元素的地址return 0;
}
2strlen——注意实参是地址计算字符串的长度统计的是‘\0’之前的字符个数
#includestdio.hint main()
{char arr[] { a,b,c,d,e,f };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));return 0;
}
答案解析
#includestdio.h
#includestring.hint main()
{char arr[] { a,b,c,d,e,f };//没有\0,不知道\0在哪printf(%d\n, strlen(arr));//随机数传的是数组首元素地址类型char*printf(%d\n, strlen(arr 0));//随机数传的是数组首元素地址类型char*//printf(%d\n, strlen(*arr));//err,strlen(a)--str(97),非法访问//printf(%d\n, strlen(arr[1]));//err,b-98,和上面代码类似非法访问printf(%d\n, strlen(arr));//随机值传的是数组指针的地址数组指针的地址也是从数组起始地址开始的类型char (*)[6]printf(%d\n, strlen(arr 1));//随机值-6arr1向后跳过整个数组的地址类型char (*)[6]printf(%d\n, strlen(arr[0] 1));//随机值-1arr[0]1是数组第二个元素的地址类型char*return 0;
}
情景2 例如char arr[] abcdef; 1sizeof——计算的是操作数类型的大小
#includestdio.hint main()
{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));return 0;
}
答案分析
#includestdio.hint main()
{char arr[] abcdef;printf(%d\n, sizeof(arr));//7字节数组名单独放在sizeof内部计算的是整个数组的大小printf(%d\n, sizeof(arr 0));//4/8字节arr0--arr[0]是数组首元素的地址类型是char*printf(%d\n, sizeof(*arr));//1字节*arr--arr[0]是数组首元素计算的是首元素大小printf(%d\n, sizeof(arr[1]));//1字节arr[1]是第二个元素计算的是第二个元素的大小printf(%d\n, sizeof(arr));//4/8字节arr是取出整个数组的地址类型数组指针char (*)[7]printf(%d\n, sizeof(arr 1));//4/8字节arr1是跳过整个数组的地址类型还是数组指针char (*)[7]printf(%d\n, sizeof(arr[0] 1));//4/8字节arr[0]1是数组第二个元素的地址类型char*return 0;
}
2strlen——注意实参是地址计算字符串的长度统计的是‘\0’之前的字符个数
#includestdio.h
#includestring.hint main()
{char arr[] abcdef;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));return 0;
}
答案解析
#includestdio.h
#includestring.hint main()
{char arr[] abcdef;//字符串后默认\0为结束标志//a b c d e f \0printf(%d\n, strlen(arr));//6字节传的是数组首元素的地址strlen从数组首元素地址开始统计\0之前的字符个数类型char*printf(%d\n, strlen(arr 0));//6字节,传的是数组首元素的地址strlen从数组首元素地址开始统计\0之前的字符个数类型char*//printf(%d\n, strlen(*arr));//err,*arr--a,strlen(a)--strlen(97),传给strlen是一个非法的地址造成非法访问//printf(%d\n, strlen(arr[1]));//errarr[1]--b--98,同上传给strlen是一个非法的地址造成非法访问printf(%d\n, strlen(arr));//6字节传的是整个数组的地址整个数组的地址也是从数组起始地址开始统计\0之前的字符个数类型char (*)[7]printf(%d\n, strlen(arr 1));//随机值,arr1跳过整个数组的地址类型char (*)[7]printf(%d\n, strlen(arr[0] 1));//5字节,传的是第二个元素的地址return 0;
}
字符指针——指向一个常量字符串的首元素地址
1sizeof操作符——计算操作数类型的大小
#includestdio.hint main()
{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));return 0;
}
答案解析
#includestdio.hint main()
{char* p abcdef;//p指针变量指向字符串首元素的地址printf(%d\n, sizeof(p));//4/8字节p指针变量printf(%d\n, sizeof(p 1));//4/8字节p1是b的地址printf(%d\n, sizeof(*p));//1字节*p--a--字符计算的是字符的大小printf(%d\n, sizeof(p[0]));//1字节p[0]--*(p0)--a,同上printf(%d\n, sizeof(p));//4/8字节p是二级指针指向变量p的地址printf(%d\n, sizeof(p 1));//4/8字节p1是跳过p变量后的地址printf(%d\n, sizeof(p[0] 1));//4/8字节p[0]--a,p[0]就是a的地址1就是b的地址return 0;
}
2strlen——注意实参是地址计算字符串的长度统计的是‘\0’之前的字符个数
#includestdio.h
#includestring.hint main()
{char* p abcdef;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;
}
答案解析
#includestdio.h
#includestring.hint main()
{char* p abcdef;//p是指针变量指向字符串的首元素地址printf(%d\n, strlen(p));//6字节传的是a的地址printf(%d\n, strlen(p 1));//5字节传的b的地址//printf(%d\n, strlen(*p));//err,*p--a--97,传给strlen一个非法地址造成非法访问//printf(%d\n, strlen(p[0]));//err,同上printf(%d\n, strlen(p));//随机值p拿到的是p变量的起始地址从这开始求字符串长度不知道\0printf(%d\n, strlen(p 1));//随机值p1是跳过p变量的地址从这开始求字符串长度也不知道\0位置printf(%d\n, strlen(p[0] 1));//5字节p[0]1--是b的地址从b开始数字符串长度return 0;
}二维数组 深入了解二维数组 二维数组可以看成一维数组的数组即一行就是是一个元素。 所以二维数组的首元素地址即第一行的地址。 例如下图 1sizeof操作符——计算操作数类型的大小
#includestdio.hint main()
{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]));return 0;
}答案分析
#includestdio.hint main()
{int a[3][4] { 0 };printf(%d\n, sizeof(a));//48字节二维数组名单独放在sizeof内部计算的是整个数组的大小printf(%d\n, sizeof(a[0][0]));//4字节a[0][0]是第一行第一个元素printf(%d\n, sizeof(a[0]));//16字节a[0]是第一行的数组名数组名单独放在sizeof内部//计算的就是数组(第一行)的大小printf(%d\n, sizeof(a[0] 1));//4/8字节,a[0]作为第一行的数组名没有单独放在sizeof内部没有取地址//表示的就是数组的首元素地址a[0]即a[0][0]的地址a[0]1就是第一行第二个元素的地址printf(%d\n, sizeof(*(a[0] 1)));//4字节a[0]1是第一行第二个元素的地址解引用得到元素printf(%d\n, sizeof(a 1));//4/8字节a是二维数组的数组名没有单独放在sizeof内部数组名就是二维数组首元素地址//就是第一行的地址那a1就是第二行的地址类型数组指针int (*)[4]printf(%d\n, sizeof(*(a 1)));//16字节(a1)是第二行的地址解引用得到第二行printf(%d\n, sizeof(a[0] 1));//4/8字节a[0]是第一行的地址1是第二行的地址printf(%d\n, sizeof(*(a[0] 1)));//16字节a[0]1是第二行的地址解引用得到第二行计算的就是第二行的大小printf(%d\n, sizeof(*a));//16字节a没有单独放在sizeof内部表示二维数组首元素的地址就是第一行的地址//解引用得到第一行计算的是第一行的大小printf(%d\n, sizeof(a[3]));//16个字节如果存在第四行a[3]就是第四行的数组名单独放在sizeof计算的是第四行的大小return 0;
}
总结 sizeof是操作符
1sizeof内部的表达式是不计算的。
#includestdio.hint main()
{int a 2;short s 3;printf(%d\n, sizeof(s a 3));printf(%d\n, s);return 0;
}
运行结果 tip①sizeof在编译时就执行了而表达式求值在运行时才执行 ②表达式求值的两个属性值属性和类型属性。
2sizeof只关注操作数占用内存空间的大小单位是字节不关心内存中存放的是什么。 strlen是库函数
1strlen是求字符串长度的统计的是\0之前出现的字符个数一定要找到\0才算结束所以可能存在越界访问的。