如果是大佬可以直接跳过解析,直接看结果即可.
目录
前言
一,代码一
解析
结果
二.代码二
解析
结果
三.代码三
解析
结果
四.代码四
解析
结果
五.代码五
解析
结果
总结
本篇文章主要讲解指针和数组在笔试中所遇到的问题及细节
数组名的意义:
1. sizeof(数组名),这里的数组名表示整个数组,计算的是整个数组的大小。
2. &数组名,这里的数组名表示整个数组,取出的是整个数组的地址。
3. 除此之外所有的数组名都表示首元素的地址。
指针:指针存放的是地址,标识一块地址空间,指针让内存访问更方便。
指针(地址)的大小在32位是4字节 ,在64位下是8字节.
#define _CRT_SECURE_NO_WARNINGS 1
#include
//一维数组
int 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;
}
printf("%d\n", sizeof(a));
由于是sizeof(数组名),所以sizeof(a)中的数组名a代表着整个数组,计算出来是整个数组的大小,a数组有4个元素,每个元素的数据类型为int,所以结果为16.
printf("%d\n", sizeof(a + 0));
sizeof(a+0),既不是sizeof(数组名),也不是&数组名,所以这里的a代表着数组首元素的地址,a+0也是代表着首元素的地址,指针(地址)的大小在32位是4字节 ,在64位下是8字节.所以答案是4或者8.
printf("%d\n", sizeof(*a));
这里的a代表的是首元素地址,解引用得到的是首元素1,所的大小为4,结果为4.
printf("%d\n", sizeof(a + 1));
这里的a代表的是首元素地址,a+1代表第二个元素地址,指针(地址)的大小在32位是4字节 ,在64位下是8字节,所以答案是4或者8.
printf("%d\n", sizeof(a[1]));
a[1]为该数组第二个元素为2,数据类型为int,大小为4个字节,答案为4.
printf("%d\n", sizeof(&a));
&a的地址为整个数组的地址,指针(地址)的大小在32位是4字节 ,在64位下是8字节,所以答案是4或者8.
printf("%d\n", sizeof(*&a));
&a的地址为整个数组的地址,解引用为整个数组,即等于sizeof(a),所以结果为16.
printf("%d\n", sizeof(&a + 1));
&a的地址为整个数组的地址,&a+1则跳过是整个数组,但结果还是地址指针(地址)的大小在32位是4字节 ,在64位下是8字节,所以答案是4或者8.这里配图进行理解.
printf("%d\n", sizeof(&a[0]));
a[0]为第一个元素,&a[0]为第一个元素的地址,指针(地址)的大小在32位是4字节 ,在64位下是8字节,所以答案是4或者8.
printf("%d\n", sizeof(&a[0] + 1));
&a[0]为第一个元素的地址,&a[0]+1为第二个元素的地址,指针(地址)的大小在32位是4字节 ,在64位下是8字节,所以答案是4或者8.
左边结果在32为下的结果,右边结果在64为下的结果
#define _CRT_SECURE_NO_WARNINGS 1
#include
#include
//字符数组
int main() {
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));
return 0;
}
printf("%d\n", sizeof(arr));
sizeof(数组名)计算的是整个数组的大小,sizeof(arr),arr数组有六个元素每个元素的数据类型为char,所以结果为6.
printf("%d\n", sizeof(arr + 0));
arr这里代表的是首元素的地址,arr+0还是首元素的地址,指针(地址)的大小在32位是4字节 ,在64位下是8字节,所以答案是4或者8.
printf("%d\n", sizeof(*arr));
arr这里代表首元素地址,解引用为数组第一个元素a,数据类型为char,大小为1,所以结果为1.
printf("%d\n", sizeof(arr[1]));
arr[1]为数组第一个元素a,数据类型为char,大小为1,所以结果为1.
printf("%d\n", sizeof(&arr));
&arr为整个数组的地址,指针(地址)的大小在32位是4字节 ,在64位下是8字节,所以答案是4或者8.
printf("%d\n", sizeof(&arr + 1));
&arr为整个数组的地址,&arr+1跳过整个数组,但结果还是地址指针(地址)的大小在32位是4字节 ,在64位下是8字节,所以答案是4或者8.这里配图进行理解.
printf("%d\n", sizeof(&arr[0] + 1));
&arr[0]为第一个元素的地址,&arr[0]+1为第二个元素的地址,指针(地址)的大小在32位是4字节 ,在64位下是8字节,所以答案是4或者8.
printf("%d\n", strlen(arr));
arr这里代表的是整个数组的地址,这里就要了解strlen函数的性质,strlen() 函数从字符串的开头位置依次向后计数,直到遇见\0,然后返回计时器的值。最终统计的字符串长度不包括\0。
由于arr数组里没有\0元素,所以还会一直找下去,不知道在哪里会遇到\0,所以给出的答案是一个随机值.
printf("%d\n", strlen(arr + 0));
arr为第一个元素的地址,arr+0为第一个元素的地址,跟上一个代码运行情况相同,所以在这里不在继续解释,答案是随机值,且与上一个代码运行结果相同.
printf("%d\n", strlen(*arr));
arr代表第一个元素的地址,解引用为第一个元素a,由于strlen()函数的参数是地址,就会将a的ASCII的值97当做一个地址进行访问,运行时就会出现错误,错误原因为:引发的异常: 0xC0000005: 读取位置 0x00000061 时发生访问冲突。所以该运行结果为error.
printf("%d\n", strlen(arr[1]));
arr[1]为数组的第二个元素b,与上一个代码同理,在这里不在进行解释,错误原因为:引发的异常: 0xC0000005: 读取位置 0x00000062 时发生访问冲突。所以该运行结果为error.
printf("%d\n", strlen(&arr));
&arr为整个数组的地址,跟strlen(arr)相同,由于arr数组里没有\0元素,所以还会一直找下去,不知道在哪里会遇到\0,所以给出的答案是一个随机值.
printf("%d\n", strlen(&arr + 1));
&arr为整个数组的地址,&arr+1跳过整个数组,在这里我们还配图解释.
由于跳过整个数组,该数组有六个元素,所以答案应为,上一个代码的随机值-6
printf("%d\n", strlen(&arr[0] + 1));
&arr[0]为第一个元素的地址,&arr[0]+1为第二个元素的地址,所以根据上个代码理解,该代码的答案为随机值-1.
左边结果在32为下的结果,右边结果在64为下的结果,由于有错误代码我中间省略用error代替.
感兴趣的小伙伴可以试一下错误代码会提示什么问题,以便更深入了解.
#define _CRT_SECURE_NO_WARNINGS 1
#include
#include
//字符数组
int 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));
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;
}
注意:这里数组arr是用字符串初始化的数组,所以该数组的元素有7个,第七个元素为"\0"
printf("%d\n", sizeof(arr));
sizeof(arr)为整个数组的大小,该数组有7个元素,每个元素的数据类型为char,所以答案为7.
printf("%d\n", sizeof(arr + 0));
arr为首元素的地址arr+0也是首元素的地址,指针(地址)的大小在32位是4字节 ,在64位下是8字节,所以答案是4或者8.
printf("%d\n", sizeof(*arr));
arr为第一个元素的的地址,解引用为第一个元素a,数据类型为char,所以答案为1.
printf("%d\n", sizeof(arr[1]));
arr[1]为数组的第二个元素b,数据类型为char,所以答案为1.
printf("%d\n", sizeof(&arr));
&arr为整个元素的地址,指针(地址)的大小在32位是4字节 ,在64位下是8字节,所以答案是4或者8.
printf("%d\n", sizeof(&arr + 1));
&arr为整个数组的地址,&arr+1跳过整个数组,这里为了更方便理解我们配图解释.
指针(地址)的大小在32位是4字节 ,在64位下是8字节,所以答案是4或者8.
printf("%d\n", sizeof(&arr[0] + 1));
&arr[0]+1为数组第二个元素的地址,指针(地址)的大小在32位是4字节 ,在64位下是8字节,所以答案是4或者8.
printf("%d\n", strlen(arr));
arr为整个数组的地址,strlen() 函数从字符串的开头位置依次向后计数,直到遇见\0,然后返回计时器的值。最终统计的字符串长度不包括\0。所以答案为6.
printf("%d\n", strlen(arr + 0));
arr+0为第一个元素的地址,所以答案为6.
printf("%d\n", strlen(*arr));
arr代表第一个元素的地址,解引用为第一个元素a,由于strlen()函数的参数是地址,就会将a的ASCII的值97当做一个地址进行访问,运行时就会出现错误,错误原因为:引发的异常: 0xC0000005: 读取位置 0x00000061 时发生访问冲突。所以该运行结果为error.
printf("%d\n", strlen(arr[1]));
arr[1]为数组的第二个元素b,与上一个代码同理,在这里不在进行解释,错误原因为:引发的异常: 0xC0000005: 读取位置 0x00000062 时发生访问冲突。所以该运行结果为error.
printf("%d\n", strlen(&arr));
&arr为整个数组的地址,所以答案为6.注意:这里是strlen,不要跟sizeof搞混了.
printf("%d\n", strlen(&arr + 1));
还是这张图.
所以还会一直找下去,不知道在哪里会遇到\0,所以给出的答案是一个随机值.
注:随机值不要与其他值进行比较
printf("%d\n", strlen(&arr[0] + 1));
&arr[0]为第一个元素的地址,&arr[0]+1为第二个元素的地址,所以答案为5.
左边结果在32为下的结果,右边结果在64为下的结果,由于有错误代码我中间省略用error代替.
#define _CRT_SECURE_NO_WARNINGS 1
#include
#include
//字符数组
int 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));
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));
}
这里便于更直观,请看图!
printf("%d\n", sizeof(p));
p是个指针(存的是数组首元素的地址),指针(地址)的大小在32位是4字节 ,在64位下是8字节,所以答案是4或者8.
printf("%d\n", sizeof(p + 1));
p为数组首元素地址,p+1为数组第二个元素地址,指针(地址)的大小在32位是4字节 ,在64位下是8字节,所以答案是4或者8.
printf("%d\n", sizeof(*p));
*p为数组首元素a,所以为1.
printf("%d\n", sizeof(p[0]));
p[0]为数组的第一个元素,也可以写成*(p+0)这两个是等价的,所以答案为1.
printf("%d\n", sizeof(&p));
&p是p的地址,指针(地址)的大小在32位是4字节 ,在64位下是8字节,所以答案是4或者8.
printf("%d\n", sizeof(&p + 1));
&p+1为p地址后面的地址具体指向哪里不知道,但还是个地址,所以答案是4或者8.
printf("%d\n", sizeof(&p[0] + 1));
&p[0]为首元素地址,&p[0]+1为数组第二个元素的地址,所以答案是4或者8.
printf("%d\n", strlen(p));
p为数组首元素地址,所以答案为6.
printf("%d\n", strlen(p + 1));
p+1为数组第二个元素的地址,所以答案为5.
printf("%d\n", strlen(*p));
*p为数组第一个元素a,程序错误,不在进行过多解释,与上面的程序错误相同.
printf("%d\n", strlen(p[0]));
p[0]为数组第一个元素a,程序错误,不在进行过多解释,与上面的程序错误相同.
printf("%d\n", strlen(&p));
&p为p的地址,后面是否在哪里存在\0不知道,所以是随机值.
printf("%d\n", strlen(&p + 1));
与上一个代码同理,也是随机值.
printf("%d\n", strlen(&p[0] + 1));
&p[0]+1为数组第二个元素的地址,所以答案为5.
左边结果在32为下的结果,右边结果在64为下的结果,由于有错误代码我中间省略用error代替.
#define _CRT_SECURE_NO_WARNINGS 1
#include
//二维数组
int 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]));
}
printf("%d\n", sizeof(a));
sizeof(数组名)计算的是整个数组的大小,所以答案为48.
printf("%d\n", sizeof(a[0][0]));
a[0][0]为数组第一个元素,数据类型为int,所以答案为4.
printf("%d\n", sizeof(a[0]));
a[0]表示数组的第一行元素,由于是二维数组所以答案为16.
如果不理解的话可以认为a[0]为第一行元素的数组名.
printf("%d\n", sizeof(a[0] + 1));
a[0]+1为数组的第一行第二个元素的地址,所以答案为4或8.
printf("%d\n", sizeof(*(a[0] + 1)));
*(a[0]+1)为数组的第一行第二个元素,数据类型为int,所以答案为4.
printf("%d\n", sizeof(a + 1));
a为二维数组的第一行的地址,a+1为数组第二行的地址,所以答案为4或8.
printf("%d\n", sizeof(*(a + 1)));
*(a+1)为第二行元素,所以答案为16.
printf("%d\n", sizeof(&a[0] + 1));
&a[0]+1为数组第二行元素的地址,所以答案为4或8.
printf("%d\n", sizeof(*(&a[0] + 1)));
*(&a[0] + 1))为数组第二行元素,所以答案为16.
printf("%d\n", sizeof(*a));
*a为数组第一行地址,所以答案为16.
printf("%d\n", sizeof(a[3]));
a[3]这里有小伙伴就会发现数组越界了,非法访问了吗?所以程序应该出现错误,实则不然.这里就要深入了解以下sizeof()函数了.sizeof()内部的表达式是不计算的,不会真的去访问的,所以不会出现非法访问的问题,所以其实不存在也能通过类型计算大小.所以答案为16.
便于理解sizeof()函数我写了一段代码来分析.
#define _CRT_SECURE_NO_WARNINGS 1
#include
int main() {
short b = 5;
int a = 4;
printf("%d\n", sizeof(b = a + 6));
printf("%d\n", b);
}
这里我们分析以下结果是什么呢?
经过分析我得出的答案是
2
5
sizeof()内部的表达式是不计算的,这样大家能够理解了吗.
那我们运行一下,左边结果在32为下的结果,右边结果在64为下的结果
呼呼终于完事了,离成功又进了一部,我把我学习c语言的经历分享出来,大家一起进步!
在这里还是感谢那些可以看到底的小伙伴,学到就是赚到,学到才是王道.哈哈哈
鸡你太美!
数组名的意义:
1. sizeof(数组名),这里的数组名表示整个数组,计算的是整个数组的大小。
2. &数组名,这里的数组名表示整个数组,取出的是整个数组的地址。
3. 除此之外所有的数组名都表示首元素的地址。
指针:指针存放的是地址,标识一块地址空间,指针让内存访问更方便。
指针(地址)的大小在32位是4字节 ,在64位下是8字节.
二维数组的数组名为第一行的元素记住哦!
小小up制作不易请给点赞吧!球球了.