【问题标题】:Is there a way to print integers normally that are assigned to a pointer array?有没有办法打印通常分配给指针数组的整数?
【发布时间】:2021-10-19 11:07:30
【问题描述】:

我正在创建一个涉及指针和数组的程序,但我偶然发现了一个问题。 基本上,我创建了三个整数,它们将从用户的输入中获取其值,然后将它们全部声明在一个数组中,以便在一个循环中更改它们的所有值。

然后我声明了一个指针,它使用循环内的数组来做到这一点。

期望循环中的指针数组以正常顺序打印出数据,而不是向后打印。

请注意,我是 C++ 编程的初学者,并且仍在学习指针。

我已尝试更改索引号

pntr = &salary[3];

但是 3 是唯一一个打印出循环中每个输入的值。 0 不起作用,同样适用于 1、2、4 等等。

我希望新输出具有相同的语法(salary1、salary2、salary3),而不是反转它(salary3、salary2、salary1)以打印输入的值。

代码如下:

#include <iostream>
using namespace std;

int main() {
    int salary1, salary2, salary3;
    cout << "Enter salary for John: ";
    cin >> salary1;
    cout << "Enter salary for Mark: ";
    cin >> salary2;
    cout << "Enter salary for Nathan: ";
    cin >> salary3;
    cout << "Name \t Age \t Position \t Salary" << endl;
    cout << "John \t 16 \t Engineer \t " << salary1 << endl;
    cout << "Mark \t 16 \t Scouter \t " << salary2 << endl;
    cout << "Nathan \t 17 \t Manager \t " << salary3 << endl;
    int salary[3] = {salary1, salary2, salary3};
    int *pntr;
    pntr = &salary[3];
    for(int x = 0; x < 3; x++) {
        cout << "Enter new salary: " << endl;
        cin >> *(pntr + x);
        cout << "Salary 1:" << salary1 << endl;
        cout << "Salary 2:" << salary2 << endl;
        cout << "Salary 3:" << salary3 << endl;
    }
    cout << "Name \t Age \t Position \t Salary" << endl;
    cout << "John \t 16 \t Engineer \t " << salary1 << endl;
    cout << "Mark \t 16 \t Scouter \t " << salary2 << endl;
    cout << "Nathan \t 17 \t Manager \t " << salary3 << endl;
    return 0;
}

【问题讨论】:

  • 我认为您对“pntr”的初始化会导致它指向“salary”末尾的 1,因此“pntr+x”指向您要访问的数据。
  • 你为什么要cin &gt;&gt; *(pntr + x);?你想在打印出用户刚刚输入的以前的工资之前覆盖工资吗?
  • 马克是对的,当您执行pntr+x 并取消引用它时,您正在访问超出工资数组边界的内存,因为您已经将 pntr 设置为指向工资数组之后的一个。
  • 如前所述,pntr = &amp;salary[3]; 立即将pntr 置于数组范围之外。 pntr = salary; 就足够了,但我根本不会费心使用指针。
  • 我试过 pntr = 薪水;但它不会注册用户的输入和输出新值。

标签: c++ arrays pointers


【解决方案1】:

如果你想改变salary1salary2salary3的值,你应该为int*声明salary[3],而不是int

int salary[3] = { salary1, salary2, salary3 };

int* salary[3] = { &amp;salary1, &amp;salary2, &amp;salary3 };

那么你的指针也应该是双指针:

int** pntr = salary;

最后你应该取消引用 (pntr + x) 两次,因为它现在是双指针:

cin &gt;&gt; **(pntr + x);

完整代码:

#include <iostream>
using namespace std;
int main() {
    int salary1, salary2, salary3;

    cout << "Enter salary for John: ";
    cin >> salary1;
    cout << "Enter salary for Mark: ";
    cin >> salary2;
    cout << "Enter salary for Nathan: ";
    cin >> salary3;
    cout << "Name \t Age \t Position \t Salary" << endl;
    cout << "John \t 16 \t Engineer \t " << salary1 << endl;
    cout << "Mark \t 16 \t Scouter \t " << salary2 << endl;
    cout << "Nathan \t 17 \t Manager \t " << salary3 << endl;

    int* salary[3] = { &salary1, &salary2, &salary3 };
    int** pntr = salary;

    for (int x = 0; x < 3; x++) {
        cout << "Enter new salary: " << endl;
        cin >> **(pntr + x);
        cout << "Salary 1:" << salary1 << endl;
        cout << "Salary 2:" << salary2 << endl;
        cout << "Salary 3:" << salary3 << endl;
    }

    cout << "Name \t Age \t Position \t Salary" << endl;
    cout << "John \t 16 \t Engineer \t " << salary1 << endl;
    cout << "Mark \t 16 \t Scouter \t " << salary2 << endl;
    cout << "Nathan \t 17 \t Manager \t " << salary3 << endl;


    return 0;
}

你可能对这条线还有一些疑问

int** pntr = salary;

pntrint** 类型,salaryint*[3] 类型,

数组的地址表示数组的第一个元素的地址,

所以它是一样的:

int** pntr = &amp;salary[0];

你可以很容易地找到它

只需执行以上两个不同初始化的整个代码

不清楚的可以写int** pntr = &amp;salary[3];

&amp;salary[3]代表salary[3]的地址,

salary[3] 只是一个int* 值,而不是数组“类型”

表示数组salary的第三个元素的地址,记住了

只有在初始化时index表示数组的大小,初始化后index表示值

【讨论】:

  • 这正是我要找的,非常感谢!
  • 为什么不首先将所有三个值都存储在一个数组中,而不是将salary1salary2salary3 作为三个单独的变量,然后构造一个指向这些变量的指针数组?
  • 我试图找出是否可以在数组中删除三个单独的值并稍后在数组中使用,所以我以这种方式声明它们。
【解决方案2】:

您的直接问题是双重的。您初始化指针并立即将其指向数组之外。如果你有一个容量为 3 的数组,你的索引如下:

 --- --- ---
| 0 | 1 | 2 |
 --- --- ---

索引 3 不在您的数组中,因此您的指针指向它之外。将您的初始化更改为:int* pntr = salary;

然后,您的另一个问题是,当您将新工资放入数组时,您再也不会访问该数组。相反,您再次查看您从未修改过的三个 int 变量。这个练习也不需要变量。

这是解决当前问题的代码的精简版本。

#include <iostream>

int main() {
  int salary1, salary2, salary3;

  std::cout << "Enter salary for John: ";
  std::cin >> salary1;
  std::cout << "Enter salary for Mark: ";
  std::cin >> salary2;
  std::cout << "Enter salary for Nathan: ";
  std::cin >> salary3;
  std::cout << "Name \t Age \t Position \t Salary" << '\n';
  std::cout << "John \t 16 \t Engineer \t " << salary1 << '\n';
  std::cout << "Mark \t 16 \t Scouter \t " << salary2 << '\n';
  std::cout << "Nathan \t 17 \t Manager \t " << salary3 << '\n';

  int salary[3] = {salary1, salary2, salary3};
  int *pntr = salary;  // CHANGED

  // CHANGE: Print the array
  for (auto i : salary) {
    std::cout << i << '\n';
  }

  for (int x = 0; x < 3; x++) {
    std::cout << "Enter new salary: ";
    std::cin >> *(pntr + x);
    std::cout << "Salary " << x + 1 << ": " << salary[x]
              << '\n';  // CHANGED: Access the array
  }

  // CHANGE: Print the array
  for (auto i : salary) {
    std::cout << i << '\n';
  }

  return 0;
}

您有一个仅用于薪水的数组似乎很奇怪。这是对您的程序的全新尝试,它利用了一些您可能还没有见过的 C++ 概念,但我希望您能够体会到它使您的代码变得多么简单。请注意,我不会将这段代码称为最佳实践,但我认为它的目的是展示一些新原则。

最大的设计变化是,我们有一组人员,而不是仅仅一组薪水,如果需要,我们可以更改他们的薪水。

#include <iomanip>
#include <iostream>
#include <vector>

struct Person {
  std::string name;
  int age;
  std::string title;
  int salary;
};

void print_table(const std::vector<Person>& emp) {
  std::size_t maxNameLength = 0;
  std::size_t maxTitleLength = 0;
  for (auto i : emp) {
    if (i.name.length() > maxNameLength) maxNameLength = i.name.length();
    if (i.title.length() > maxTitleLength) maxTitleLength = i.title.length();
  }

  std::cout << std::setw(maxNameLength + 1) << "Name"
            << "|Age|" << std::setw(maxTitleLength + 1) << "Title"
            << "|Salary\n";
  for (auto i : emp) {
    std::cout << std::setw(maxNameLength + 1) << i.name << "|" << std::setw(3)
              << i.age << "|" << std::setw(maxTitleLength + 1) << i.title << "|"
              << std::setw(6) << i.salary << '\n';
  }
}

int main() {
  std::vector<Person> employees{{"John", 16, "Engineer", 0},
                                {"Mark", 16, "Scouter", 0},
                                {"Nathan", 17, "Manager", 0}};

  for (int x = 0; x < 3; x++) {
    std::cout << "Enter new salary for " << employees[x].name << ": ";
    std::cin >> employees[x].salary;
  }

  print_table(employees);

  return 0;
}

输出:

Enter new salary for John: 34
Enter new salary for Mark: 45
Enter new salary for Nathan: 56
   Name|Age|    Title|Salary
   John| 16| Engineer|    34
   Mark| 16|  Scouter|    45
 Nathan| 17|  Manager|    56

【讨论】:

  • 我从来没有这样想过,这让我对我正在学习的东西有了新的认识。谢谢!
【解决方案3】:
#include <iostream>

using namespace std;
int main() {
    int salary1, salary2, salary3;

    cout << "Enter salary for John: ";
    cin >> salary1;
    cout << "Enter salary for Mark: ";
    cin >> salary2;
    cout << "Enter salary for Nathan: ";
    cin >> salary3;
    cout << "Name \t Age \t Position \t Salary" << endl;
    cout << "John \t 16 \t Engineer \t " << salary1 << endl;
    cout << "Mark \t 16 \t Scouter \t " << salary2 << endl;
    cout << "Nathan \t 17 \t Manager \t " << salary3 << endl;

    int salary[3] = {salary1, salary2, salary3};

    for (int x = 0; x < 3; x++) {
      cout << "Enter new salary: " << endl;
      cin >> * (salary + x);
      cout << "Salary " << x << ": " << * (salary + x) << endl;
    }

    cout << "Name \t Age \t Position \t Salary" << endl;
    cout << "John \t 16 \t Engineer \t " << salary[0] << endl;
    cout << "Mark \t 16 \t Scouter \t " << salary[1] << endl;
    cout << "Nathan \t 17 \t Manager \t " << salary[2] << endl;
}

也许你最终想要这样的东西?

注意事项:

  • 数组衰减为指针,因此您不需要额外的指针
  • salary1、salary2、salary3 不会像你预期的那样被覆盖,因为它们从未被触及。当你这样做时,salary 数组中的内存将被覆盖cin &gt;&gt; *(salary+ x);
  • 所以最后你想打印数组中的内容而不是salary1、2、3变量(可能)

【讨论】:

  • 我还没有真正掌握指针的全部概念,但这对我的学习之旅很有帮助。谢谢!
猜你喜欢
  • 1970-01-01
  • 2020-06-02
  • 1970-01-01
  • 2014-04-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-03
  • 1970-01-01
相关资源
最近更新 更多