【问题标题】:Cant get char pointer to print correctly无法正确打印字符指针
【发布时间】:2015-09-19 02:21:57
【问题描述】:

我对指针比较陌生,慢慢学习如何使用它们。我在这里遇到了一个问题,我已经尝试了所有的选择。我有一个指针 char* pMonthName;指向monthName,它是一个字符数组。我试图用 cout

char monthName[12][15];

// initialize
strcpy_s(monthName[0], "january");
strcpy_s(monthName[1], "febuary");
strcpy_s(monthName[2], "march");
strcpy_s(monthName[3], "april");
strcpy_s(monthName[4], "may");
strcpy_s(monthName[5], "june");
strcpy_s(monthName[6], "july");
strcpy_s(monthName[7], "august");
strcpy_s(monthName[8], "septempber");
strcpy_s(monthName[9], "october");
strcpy_s(monthName[10], "november");
strcpy_s(monthName[11], "december");

// create a char pointer
char* pMonthName;

// make pointer point to the array
pMonthName = &monthName[12][15];

// print array using the pointer
for (row = 0; row < 12; row++)
{
    length = strlen(monthName[row]); 
    for (col = 0; col < length; col++)
    {
        cout << *pMonthName;
    }
    cout << endl;
}

【问题讨论】:

  • 我是 inb4 "febuary""septempber"。您提供的代码甚至无法编译,更不用说重现您面临的问题......我们应该关闭这个问题,还是您会好心地产生一个mcve
  • inb4 没有月份名称[12]
  • pMonthName = &amp;monthName[12][15]; 你在这里做什么?编译器已经知道数组是 12 x 15。您在这里所做的只是将越界地址分配给指针。

标签: c++ arrays pointers char


【解决方案1】:

首先,这都是错误的,因为它无法编译:

strcpy_s(monthName[0], "january");
strcpy_s(monthName[1], "febuary");
strcpy_s(monthName[2], "march");
strcpy_s(monthName[3], "april");
strcpy_s(monthName[4], "may");
strcpy_s(monthName[5], "june");
strcpy_s(monthName[6], "july");
strcpy_s(monthName[7], "august");
strcpy_s(monthName[8], "septempber");
strcpy_s(monthName[9], "october");
strcpy_s(monthName[10], "november");
strcpy_s(monthName[11], "december");

我认为您遗漏了一个参数(中间那个),应该是 15

即使这段代码要编译,也是错误的:

pMonthName = &monthName[12][15];

要描述这有什么问题,请考虑一个鸡蛋盒可以存放 12 个鸡蛋(在egg_carton[0]egg_carton[11] 之间),而您指向的是第 13 个鸡蛋(egg_carton[12])。

更糟糕的是,有些鸡蛋可以是双黄的,这意味着您有 egg_carton[0][0]egg_carton[0][1] 来处理这两个蛋黄...但是您指向的是第三个​​的蛋黄第十三个蛋。

...然后你试图打印那个不存在的鸡蛋的不存在的蛋黄。

pMonthName 不适合存储需要两级间接的东西,所以让我们从修复它开始。您肯定想要一个 指向 12 个 chars 数组的指针(您可以取消引用两次,就好像它是 一个数组的数组),而不仅仅是一个指向char 的指针(您只能取消引用一次,就好像它只是一个数组),对吧?这种声明是这样写的:

char (*pMonthName)[12];

monthName 的表达式将从数组(数组)类型的表达式转换为指针(到数组)类型的表达式。花点时间解读一下,也许再读一遍(和第三遍),然后再继续。

此规则有一些例外情况(例如,&amp;address-ofsizeof 运算符的操作数不会进行此转换)。您需要了解这些转换将发生在您的代码中:

  • char[15] 的表达式隐式变为 char *
  • char[12][15] 的表达式隐式变为 char (*)[15]

所以如果我们写pMonthName = monthName;(甚至monthName[x]),那么monthName(即char[12][15])将被转换为char (*)[15]。然后你就可以写pMonthName[index_of_month],它等于monthName[index_of_month]

这是另一个例子:给定一个像char *pMonthName; 这样的声明,您可以像这样分配地址一个月(不是月份数组):pMonthName = monthName[index_of_month];,而monthName[index_of_month](即char[15])将在此表达式中隐式转换为char *

【讨论】:

  • strcpy_s 的使用应该没问题,因为有一个 2 参数重载,它使用模板来推断缓冲区大小。
猜你喜欢
  • 2015-12-16
  • 2018-06-10
  • 2023-03-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-15
  • 1970-01-01
  • 2023-03-26
相关资源
最近更新 更多