C语言指针代码输出结果求助:对多段printf输出存疑
逐段拆解这段C代码的输出逻辑
嘿,我来帮你把这段代码里每个输出的来龙去脉讲清楚,重点解决你困惑的点~
先理清初始化的关键数据
在看各个printf之前,先把代码里的核心变量初始化情况列出来,这是理解输出的基础:
- 全局变量
k = 10,但main函数里定义了局部变量k = 11,所以main里的代码默认用局部k,全局k只有在没有局部k的函数里才会被访问。 - 数组
f[DIM](DIM=8)通过for循环初始化:f[i] = i % DIM + 1,所以最终数组元素是:f[0]=1, f[1]=2, f[2]=3, f[3]=4, f[4]=5, f[5]=6, f[6]=7, f[7]=8 - 指针
p1 = f+1:指向数组f的第二个元素f[1];p2 = &p1:是指向指针p1的二级指针;zf是字符串指针数组,zf[0]="text0", zf[1]="text1", zf[2]="text2"。
a) 第一段printf输出解析
输出:a) i=8, *f=1, f[2]=3, *(p1+5) =7
逐个拆解:
i=8:for循环的条件是i<DIM(DIM=8),当i从0循环到7后,i自增到8,此时不满足循环条件,退出循环,所以i的最终值是8。*f=1:f是数组首地址,*f等价于f[0],初始化后的值是1。f[2]=3:根据初始化规则,f[2] = 2%8 +1 = 2+1=3,这就是你困惑的点,其实是循环初始化的结果哦。*(p1+5)=7:p1指向f[1],p1+5等价于f+1+5 = f+6,指向f[6],f[6]=6%8+1=7,所以取值是7。
b) 第二段printf输出解析
输出:b) k=11, zf[1]=text1, **zf=text0, **p2=2
这里注意一个小细节:代码里的printf格式串写的是**zf=%s,但实际传入的参数是*zf(不是**zf),否则用%s输出char类型会出错,我们按实际输出解析:
k=11:这里访问的是main函数里的局部变量k,不是全局k,所以值是11。zf[1]=text1:zf是字符串指针数组,zf[1]直接指向第二个字符串"text1",所以输出这个字符串。**zf=text0:实际参数是*zf,*zf指向第一个字符串"text0"的首地址,用%s输出就是整个字符串"text0"。(如果真的是**zf,那是取第一个字符串的第一个字符't',用%s会出问题)**p2=2:p2是指向p1的二级指针,*p2就是p1本身,**p2等价于*p1,也就是f[1]的值2。
c) 第三段printf输出解析
输出:c) k=11, *p3=4, f[7]=A, *p1=5
这部分要结合func函数的逻辑来看:
先看func函数的执行过程
调用p3 = func(f, k)时,func里的操作:
- 用
malloc分配了一块int大小的内存,p4指向这块内存。 *p4 = ff[3]:ff是传入的数组f,ff[3]就是f[3]=4,所以这块内存的值是4,返回p4给p3,因此*p3=4。k = k -3:这里的k是全局变量k(因为func里没有定义局部k),原来全局k=10,减3后变成7。ff[k] = 65:ff是数组f,k现在是7,所以f[7] = 65,而65是ASCII码里的'A',所以用%c输出就是'A'。
再看main里的后续操作
p1 = p1 +3:原来p1指向f[1],加3后指向f[1+3] = f[4],f[4]初始化的值是5,所以*p1=5。
k=11:这里依然访问的是main里的局部k,全局k被修改但不影响局部变量,所以还是11。
内容的提问来源于stack exchange,提问作者kai11
相关产品推荐
相关产品推荐

