You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

向接受二维数组的函数传递指针数组时的输出异常问题

为什么func函数中的printf("%s\n", *(str+1));无法输出"World"?

先看你的代码:

#include <stdio.h>
char *gstr[] = { "Hello", "World" };
void func(char str[][8]) {
    printf("%p\n", (void *)str);
    printf("%p\n", (void *)(str + 1));
    printf("%s\n", *(str + 1));
}
int main(void) {
    printf("%p\n", (void *)gstr);
    printf("%p\n", (void *)(gstr + 1));
    printf("%s\n", *(gstr + 1));
    printf("Calling Function\n");
    func(gstr);
    return 0;
}

运行输出:

0x556f11ddd010
0x556f11ddd018
World
Calling Function
0x556f11ddd010
0x556f11ddd018
$��oU

咱们直接说核心问题:你传入func的参数类型和函数期望的类型不匹配,这直接导致了指针解析出错。

  • 先看全局变量gstr:它是char *gstr[],本质是一个指针数组——数组里的每个元素都是指向字符串的char*指针。你的环境是64位系统,每个指针占8字节,所以gstr+1会偏移8字节,刚好指向数组里的第二个指针(也就是指向"World"的那个指针)。
  • 再看func的参数char str[][8]:这是声明了一个二维字符数组,当它作为函数参数时,会自动退化为指向char[8]的指针(也就是char (*str)[8])。这时候str+1的偏移量是8字节,因为它指向的是8字节大小的字符数组元素。

现在矛盾点来了:你把char**类型的gstr传给了期望char (*)[8]类型参数的func。虽然两者的地址值看起来一样(输出的前两个地址完全相同),但指针的类型决定了它如何解析内存中的内容:

  • 在main函数里,*(gstr+1)是取指针数组的第二个元素,也就是那个指向"World"的char*指针,所以printf("%s")能正确识别并打印字符串。
  • 在func函数里,str被当作char (*)[8]类型处理,*(str+1)会从str的地址偏移8字节后,取出一段8字节的内容当作字符数组。但实际上这个位置存储的是gstr数组的第二个元素(也就是指向"World"的指针值),而不是字符串本身!把指针的二进制值直接当作字符串输出,自然就会出现乱码——因为这些二进制值并不是有效的ASCII字符序列,也没有字符串结束符'\0'来终止输出。

那怎么修复?只需要把func的参数类型改成和gstr匹配的类型就行,比如写成char *str[](或者等价的char **str):

void func(char **str) {
    printf("%p\n", (void *)str);
    printf("%p\n", (void *)(str + 1));
    printf("%s\n", *(str + 1));
}

修改之后,func里的str就和main里的gstr是同一种指针类型了,*(str+1)能正确拿到指向"World"的指针,printf也就可以正常输出字符串了。

内容的提问来源于stack exchange,提问作者Shockline

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 03:44:06