c语言修炼之指针和数组笔试题解析(1.2)

前言:

书接上回,让我们继续开始今天的学习叭!废话不多说,还是字符数组的内容上代码!

char *p是字符指针,*表示p是个指针,char表示p指向的对象类型是char型!

cpp 复制代码
char*p="abcdef";

当我们把字符串abcdef的地址存放在p中时,p是存了整个字符串还是之存了a的地址呢?这得对代码进行调试啦

此时我们会发现p中的地址也就是字符串中a的地址!让我们继续开始学习啦

cpp 复制代码
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));
	return 0;
}

开始分析叭

cpp 复制代码
printf("%d\n", sizeof(p));

p中存放的是a的地址,sizeof(p)求的是地址的大小,地址的大小是4/8个字节大小

cpp 复制代码
printf("%d\n", sizeof(p + 1));

p指向字符串中a的地址,p+1则指向字符串中b的地址,sizeof(p+1)求的是地址的大小,地址大小是4/8个字节大小

cpp 复制代码
printf("%d\n", sizeof(*p));

p指向字符串中a的地址,*p指的是a,sizeof(*p)-->sizeof(a)所以大小为1字节

cpp 复制代码
printf("%d\n", sizeof(p[0]));

p0-->*(p+0)-->*(p),p中存放的是a的地址,所以*p指向a,sizeof(p0)计算的是sizeof(a)的大小,结果为1

cpp 复制代码
printf("%d\n", sizeof(&p));

p中存放的是字符串的地址,p的类型为char*,p本身也有地址,其类型为char**!所以sizeof(&p)计算的也是地址的大小,其结果为4/8

接着来分析下一个代码叭

cpp 复制代码
printf("%d\n", sizeof(&p + 1));

&p将p的地址取出在进行加1,具体的地址是啥咱也不知道,但有一点可以确定的就是sizeof(&p+1)计算的是地址的大小,地址大小是4/8个字节大小

cpp 复制代码
printf("%d\n", sizeof(&p[0] + 1));

&(*p+0)-->p的地址,&p0+1得到的是字符串中b的地址,所以此时sizeof计算的是地址的大小,地址大小是4/8字节。通过调试代码可以发现确实是b的地址

接下来我们用strlen来,上代码 !还记得strlen的特点吗?计算遇\0之前的字符个数,字符串会隐藏一个\0

cpp 复制代码
printf("%d\n", strlen(p));

p依旧是指向字符串中a的地址,strlen在计算时从a的地址开始一直到遇到\0,那么此时的计算结果为6个字节

cpp 复制代码
printf("%d\n", strlen(p + 1));

p依旧是指向字符串中a的地址,因此p+1指向的是字符串中b的地址,此时strlen在计算时从b的地址开始计算一直到遇\0,此时计算结果为5

cpp 复制代码
printf("%d\n", strlen(*p));

p依旧是指向字符串中a的地址,*p得到的就是a,还记得在上一篇中说的吗,strlen需要的参数是const char*类型的地址而不是字符a,因此strlen(*p)得到的结果是error

cpp 复制代码
printf("%d\n", strlen(p[0]));

p0-->*(p+0)-->*p-->a,解释同上,结果为error

cpp 复制代码
printf("%d\n", strlen(&p));

strlen(&p)虽然里面计算的也是地址,但是我们不知道会在什么时候遇到\0,因此此时的结果为随机值

cpp 复制代码
printf("%d\n", strlen(&p + 1));

strlen(&p+1)即使经行加1了,还是不知道啥时候会遇到\0,结果还是随机值

cpp 复制代码
printf("%d\n", strlen(&p[0] +1)

&p0-->&*(p+0)-->p,p中存放的是a的地址,因此&p0+1此时指向字符串b中的地址,strlen(&p0+1)的计算结果为5字节

欧克,解析完毕,一起来运行代码看看叭,当然啦结果错误的咱就不运行啦

以上有关于一维数组的题我们就讲解完毕啦,接下来开始二维数组的题目讲解,还记得二维数组的知识吗?二维数组的行和列都是从0开始的,以int a34为例,这个二维数组的类型是int 34,二维数组在内存中的存储是连续的,二维数组的行可以省略不写,但是列不可以省略!二维数组可以理解为一维数组的数组!一维数组的写法是int a3即数组名+ ,二维的写法是int a34可以将int a3看作是数组名,也可以写为数组名+ !将二维的每一行看成一维的元素

接下来继续看看代码叭!

cpp 复制代码
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]));
}

int a34是一个三行四列的二维数组,每个元素是int型,总共有12个元素

开始分析叭!先来第一个代码!

cpp 复制代码
 printf("%d\n", sizeof(a));

sizeof(数组名)计算的是整个数组的大小,一共有12个元素一个元素的大小为4字节,所以整个数组的大小是48字节

cpp 复制代码
 printf("%d\n", sizeof(a[0][0]));

a0是二维数组的一行,a00是第一行的第一个元素,sizeof(a00)-->sizeof(int),其计算结果为4

cpp 复制代码
 printf("%d\n", sizeof(a[0]));

a0是二维数组的第一行,sizeof(a0)计算的是整个第一行数组的大小,一行有4个元素,所以整个第一行的大小为16字节大小

cpp 复制代码
 printf("%d\n", sizeof(a[0] + 1));

sizeof(a0+1),由于不是单独放在sizeof内部,因此a0表示的是数组首元素的地址。a0+1表示的是二维数组第一行的第二个元素的地址,sizeof(a0+1)计算的是地址的大小,地址大小是4/8个字节大小

cpp 复制代码
 printf("%d\n", sizeof(*(a[0] + 1)));

上面我们分析出a0+1表示的是二维数组第一行的第二个元素的地址,所以*(a0+1)表示的是一个二维数组第一行第二个元素,sizeof计算的是元素大小,其结果为4字节

cpp 复制代码
printf("%d\n", sizeof(a + 1));

由于数组名不是单独放在sizeof内部,因此此时数组名表示的是数组首元素的地址,a+1表示数组第二个元素的地址,即二维数组第二行的地址,sizeof计算地址的大小,其结果为4/8

cpp 复制代码
  printf("%d\n", sizeof(*(a + 1)));

由上面可得a+1表示数组第二个元素的地址,即二维数组第二行的地址,对其进行解引用得到第二行整个数组大小,其结果为16

cpp 复制代码
printf("%d\n", sizeof(&a[0] + 1));

a0表示二维数组的第一行数组,&a0取出二维数组第一行数组的整个地址,&a0+1得到二维数组第二行的地址。sizeof此时计算的还是地址的大小,结果为4/8

cpp 复制代码
printf("%d\n", sizeof(*(&a[0] + 1)));

&a0取出二维数组第一行数组的整个地址,&a0+1得到二维数组第二行的整个地址,对其经行解引用再计算其大小,结果为16字节

cpp 复制代码
 printf("%d\n", sizeof(*a));

a不是单独放在sizeof内部,因此此时a表示数组首元素的地址,二维数组首元素地址a0,对其经行解引用得到整个第一行数组的大小,sizeof对其进行计算,得到结果为16字节

最后一道题啦

cpp 复制代码
printf("%d\n", sizeof(a[3]));

哦豁,a3?这个二维数组也才3行,计算a3的大小会不会越界访问呐?不会哒,这里酱酱们可以放心去计算呐!一**般来说代码要进行编译+运行才会形成可执行文件,sizeof在编译阶段就计算好结果,因此不会造成越界访问的情况!**sizeof(a3)就计算的是整个数组的大小,其结果为16字节大小

运行一下代码看看结果叭

3.指针部分

上代码!

cpp 复制代码
int main()
{
    int a[5] = { 1, 2, 3, 4, 5 };
    int* ptr = (int*)(&a + 1);
    printf("%d,%d", *(a + 1), *(ptr - 1));
    return 0;
}
//程序的结果是什么?

数组a是一个一维数组里面存放了五个元素,&a取出的是整个数组的地址此时应该用数组指针来接收,但这里将其强制类型转化为int*类型。

a表示数组首元素的地址,a+1表示数组第二个元素 的地址,*(a+1)表示数组第二个元素2,int*ptr=(int*)(&a+1),ptr的指向和&a+1的指向一致,ptr-1此时指向a4的地址,对其进行解引用得a4-->5,所以这道题的答案为2 ,5。运行一下代码看


今天的学习就到这啦,明天继续噢!

相关推荐
kkeeper~2 小时前
0基础C语言积跬步之数据在内存中的存储
c语言·数据结构·算法
qq3862461964 小时前
更新补发第6天:7天学会C语言,每天5分钟,不需要基础
c语言·for循环·循环语句·while循环·do-while循环
张暮笛10 小时前
深入浅出:C语言中的“虚表分派”
c语言
社交怪人11 小时前
【等差数列】信息学奥赛一本通C语言解法(题号1035)
c语言
不会C语言的男孩11 小时前
VS Code 中搭建 C/C++ 开发环境(MSYS2 编译器)
c语言·c++
学困昇12 小时前
Linux 信号机制详解:从 Ctrl+C 到 SIGCHLD,一文理解进程信号
linux·c语言·开发语言·人工智能·面试
AI科技星13 小时前
维度原本——基于超复数谱系的全域维度统一理论
c语言·前端·javascript·网络·electron
SoftLipaRZC13 小时前
C语言字符完全指南:字符函数与字符串函数
c语言·开发语言·算法
程序leo源14 小时前
Qt界面优化详解
linux·c语言·开发语言·c++·qt·c#
Chen_harmony14 小时前
二十二、动态内存管理
c语言·数据结构·算法