我在记住下一次使用的变量并将其打印出来时遇到问题。我解释得更多,所以要理解我在我的计划中要做什么。
我有一个人走在一个大小为a b
的矩形上。我输入起始位置x y
和开始方向的人(北= y + 1,南= y-1,东= x + 1,西= x-1 //在我的代码中它是S,J,V ,Z)。所以我的输入如下:
5 6
// a b
3 3 S
// x y s(这代表起始方向 - 北方)
现在,我输入要为其移动的人生成的移动次数d
。
我输入数字4,它可以生成3个字母:D,L,P(向前,向左转90度,向右转90度)。
4
// d
PLDL
//移动
现在,这个人应该走这些动作。因此,如果人的位置和起始方向是3 3 S
,它应该向右转(我的方向是东方但位置相同),然后向左(方向再次向北,同一位置),然后向前(现在我移动{{ 1}},我的方向仍然是北方),最后一步向左转(向西方向)。所以mi的最终位置和方向(输出)是:
y+1
希望你能理解。如果不清楚,请发表评论。
我现在得到奇怪的输出,不真实的数字。我无法弄清楚如何将变量和条件放在一起来解决它。我的代码首先是起始方向和位置,但是稍后当我生成移动时,它应该根据生成的字符串更改为最终输出。可悲的是,它没有像我期望的那样工作。你有什么建议吗?我的问题很广泛,但我希望我们可以一起解决。
3 4 Z
示例输入:
#include <iostream>
#include <string>
#include <stdlib.h>
#include <string.h>
#include <vector>
using namespace std;
int n; // pocet uloh
int a; // rozmer obdlznika a
int b; // rozmer obdlznika b
int i;
static const char alpha[] = {'D', 'L', 'P'};
char genRandom()
{
return alpha[rand() % strlen(alpha)];
}
// end of generator
// funkcia na pohyb
void pohyb (){
int x[i];
int y[i];
string sD = ""; // starting direction
string mD = ""; // middle direction (stored one for next use)
string eD = ""; // ending direction to print out in output
string d = ""; // number of generated directions eg. d=6 ==> PDDLPPD
for (int i=0; i < d.size(); i++){
if (sD[i] == 'S'){
if(d[i] == 'D'){
y[i] = (y[i]+1);
}else if(d[i] == 'L'){
mD[i] == 'Z';
}else if(d[i] == 'P'){
mD[i] == 'V';
}
}else if (sD[i] == 'J'){
if(d[i] == 'D'){
y[i] = (y[i]-1);
}else if(d[i] == 'L'){
mD[i] == 'V';
}else if(d[i] == 'P'){
mD[i] == 'Z';
}
}else if (sD[i] == 'V'){
if(d[i] == 'D'){
x[i] = (x[i]+1);
}else if(d[i] == 'L'){
mD[i] == 'S';
}else if(d[i] == 'P'){
mD[i] == 'J';
}
}else if (sD[i] == 'Z'){
if(d[i] == 'D'){
x[i] = (x[i]-1);
}else if(d[i] == 'L'){
mD[i] == 'J';
}else if(d[i] == 'P'){
mD[i] == 'S';
}
} // koniec if podmienky
eD = mD[i];
} // koniec for loopu
// vystup
for ( i = 0 ; i < n ; i++ )
{
if(!((x[i]>=0)&&(x[i]<=a) & (y[i]>=0)&&(y[i]<=b))){
cout << x[i] << ' ' << y[i] << ' ' << eD[i] << ' ' << "SPADOL" << endl;
}else{
cout << x[i] << ' ' << y[i] << ' ' << eD[i] << endl;
}
}
} // koniec funkcie pohyb
int main() {
cin >> n;
vector<int> x(n); // x position
vector<int> y(n); // y position
vector<int> d(n); // zombie directions generation ex. DPLDDP
vector<string> sD(n); // starting direction
vector<string> eD(n); // ending direction
while(!((n >= 1)&&(n <=15000)))
{
cout << "max 15000" << flush;
cin >> n;
}
cin >> a >> b;
while(!((a >= 1)&&(a <=100) & (b >= 1)&&(b <= 100)&&(a!=b)))
{
cout << "chyba max 100 alebo a!=b" << endl;
cin >> a >> b;
}
for (i = 0; i < n; i++)
{
cout << "Uloha " << i+1 << ":" << endl;
cin >> x[i];
cin >> y[i];
cin >> sD[i];
while(!((x[i]>=0)&&(x[i]<=a))) {
cout << "Try Again x: " << flush;
cin >> x[i];}
while(!((y[i]>=0)&&(y[i]<=b))) {
cout << "Try Again y: " << flush;
cin >> y[i];}
cin >> d[i];
while(!((d[i]>=1)&& (d[i]<=200))) {
cout << "Try Again d: " << flush;
cin >> d[i];}
for (int counter=0; counter<d[i]; counter++)
{
cout << genRandom();
}
cout << endl;
} // koniec for
pohyb();
system("pause");
}
和输出
3
3 5
2 2 S
8
DPLDLPDD
2 4 Z
7
PDDPDPD
2 1 J
8
PPDLDDDD
答案 0 :(得分:4)
我不会修复您的代码,而是会给您一些解释,帮助您自己理解和修复它。
首先,让我调整您对变量的理解。在编程语言中,需要存储值。一旦我们存储了一个值,我们就需要能够再次检索它,因此我们需要一种方法来描述它的存储位置。
int i = 5;
这告诉编译器创建int
值类型的实例,为其赋值5,并将其称为i
。
但是,C ++是一种范围内的语言。这意味着对任何给定名称的可见性存在限制。
int x() {
int i;
}
int y() {
i = 5; // ERROR: I not declared in this scope.
}
在上面的代码中,我们在一个范围内声明i
- x的函数体 - 但后来尝试在另一个范围内使用它。
C ++范围通常以&#39; {...}&#39;来区分,例如以下内容有效:
#include <iostream>
int i = 0; // globally visible 'i'.
void f() { std::cout << "from f i = " << i << '\n'; }
int main() { // <-- function body scope
int i = 1;
{ // inner scope
int i = 2; // new variable, called 'i', but only inside this scope.
{ // <-- another inner scope
i = 3;
f();
}
} // scope ended, the second 'i' has no gone away.
std::cout << "from end of main i = " << i << '\n';
return 0;
}
以上程序打印&#34; 0&#34;然后&#34; 1&#34;。
C ++允许我们做一些调用&#34;阴影&#34; - 我们可以在不同的范围内为不同的变量使用相同的名称。
范围也会影响&#34;生命周期&#34;变量(见http://ideone.com/fXPlB7),但我不打算这样做。
让我更清楚地说明其含义 - 变量具有相似的名称但不是相同的变量:
int i = 5;
void f(float i)
{
std::cout << "in f, i is " << i << '\n';
}
int main()
{
char i[] = "Hello";
f(3.141);
std::cout << "in main, i is " << i << '\n';
return 0;
}
该程序打印什么?
请确保您理解这一点: i 不会改变,而是在给定范围内<{1}}引用的变量。
在您的函数i
中,您有以下两行代码:
pohyb
这声明了一个新变量,在此范围内导致名称string d = ""; // number of generated directions eg. d=6 ==> PDDLPPD
for (int i=0; i < d.size(); i++){
引用它。 d
是一个空字符串。
下一行迭代d
中的所有值。空字符串中有多少个值?所以,for循环线说明了这一点:
d
0不是&lt; 0,所以循环永远不会执行。
您的下一个问题是字符串(C字符串)和字符数组之间的C ++差异。
C ++基于C,它没有&#34;字符串&#34;的第一类定义。相反,C有一个约定:&#34;字符串是一个包含0或更多字符的数组,后跟一个零值char&#34;。
int i = 0;
is i < 0?
处理&#34;字符串&#34;的所有C函数(不要与std :: strings混淆),按照这个原则操作 - 判断长度的唯一方法是计算字符,直到达到零值。
出于您的目的,您实际上想要一个字符数组,但这并不会自动使它们成为字符串。
您的代码使用char empty[1] = { 0 }; // valid, empty string. it has 1 element, the 'nul'.
char a[] = { 'a', 0 }; // represents "a", size is 2 chars, 'a' and '\0'
char hello[] = { 'h', 'e', 'l', 'l', 'o', 0 }; // size 6, 5 letters and a nul
char Hello[] = "hello"; // short-cut for writing the above
char ten[] = { '1', '0', 0 }; // '0' and 0 are not the same
char hundred[] = { '1', '0', '\0' }; // '\0' == 0
char ouch[4] = "ouch"; // ERROR: the string is actually 5 chars.
来查找char数组中的元素数 - 这是不正确的,并且可能对您的应用程序造成危险。紧跟在strlen
的3个有效元素之后的字节可以是任何内容,因此alpha
可能返回3或者它可能返回非常大的值。
您真正想要的是C关键字strlen
。
sizeof
是对事物大小的编译时确定。当X是完全限定数组时,它返回X的字节大小。请注意,这意味着您只能在全局或本地范围的数组中使用它:when you pass arrays to functions they are passed by pointer。
sizeof(X)
您对输出的期望是什么?如果您想查找,请粘贴到ideone。
对于您的代码,使用char数组看起来是正确的,因此您希望使用#include <iostream>
char hello[] = "hello"; // has size 6: 'h', 'e', 'l', 'l', 'o', 0
void f(char x[])
{
std::cout << "f(x), sizeof x = " << sizeof(x) << '\n';
}
void g()
{
char x[] = "world";
std::cout << "g() sizeof x = " << sizeof(x) << '\n';
}
void h()
{
int x[] = { 1, 2, 3, 4, 5, 6, 7 };
std::cout << "h() sizeof x = " << sizeof(x) << ", but sizeof(x[0]) = " << sizeof(x[0]) << '\n';
}
int main()
{
std::cout << "main() sizeof hello = " << sizeof(hello) << '\n';
f();
g();
h();
return 0;
}
来确定数组中有多少个字符。请记住,sizeof
以字节为单位返回大小,正式正确的方式是:
sizeof
这将采用alpha的总大小并将其除以 alpha指向/包含(char)的大小。这些值在编译时是已知的,因此编译器将执行此计算并发出等效于:
的代码size_t index = size_t(rand()) % (sizeof(alpha) / sizeof(*alpha))];
return alpha[index];
或只是
return alpha[rand() % (3 / 1)];
alpha中有3个元素,但C / C ++数组是0索引的,因此模数将为我们提供一个值[0,3],即0,1或2。
最后,您担心使用if语句。对于复杂的逻辑,有时最好的做法是将它们写出并通过手工运行。您可能希望熟悉return alpha[rand() % 3];
关键字,该关键字采用变量并将其与潜在值匹配:
switch
----编辑----
On&#34;记住&#34;范围之间的值。在函数体和嵌套范围内,这会自动发生:
#include <iostream>
#include <string>
int main()
{
std::string input;
while (std::cin.good()) {
std::cout << "Direction? (n/s/e/w/q): ";
std::getline(std::cin, input);
// if input is empty, input[0] would be undefined behavior.
if (input.empty())
continue;
switch (input[0]) // check the first character only
{
// input[0] is of type char, so we can express our values
// a character literals. we could also write the ascii values,
// e.g. for 'n' we could put "case 110:"
case 'n':
std::cout << "You have entered a dark room.\n";
break; // escape the switch, not the loop.
case 'e':
case 's': // no break, 'e' falls thru
case 'w': // still no break, 'e' and 's' fall thru
std::cout << "You can't go that way.\n";
break;
case 'q':
std::cout << "bye!\n";
return 0;
break;
default:
std::cout << "I asked you to type n, s, e, w or q, but you typed " << input << ".\n";
break;
}
}
return 0;
}
但是在函数和模块之间,你需要使它们成为函数参数。
int main() {
int i = 1;
{ // inner scope
std::cout << "inner scope\n";
{ // another inner scope
if (i == 1) {
// this is a scope
std::cout << "i = " << i << '\n'; // prints 1
}
}
}
}
这是什么印刷品?请记住:变量是本地范围的。仅仅因为它们与另一个范围内的另一个变量具有相同的名称并不会使它们连接起来。
考虑以下代码,警告:PSUEDO CODE:
#include <iostream>
int f(int i, int j, int k) {
std::cout << "f() i = " << i << ", j = " << j << ", k = " << k << '\n';
i = 10;
j = 100;
k = 300;
}
int main() {
int j = 42;
f(j, j, j);
std::cout << "in main: j = " << j << '\n';
return 0;
}
现在它可能更有意义 - 即使我们在define f - takes int as f::i, int as f::j, int as f::k
"f() i = ", f::i, ", j = ", f::j, ", k = ", f::k, '\n';
f::i = 10;
f::j = 100;
f::k = 300;
end f
define main
declare main::j as int
let main::j be 42
call f with f::i = 42, f::j = 42 f::k = 42
"in main: j = " << main::j << '\n';
end main
中更改了j
,它与我们在主要内容中看到的f
不同。
如何克服这个问题:
C ++提供了两种方法。旧的,&#39; c&#39;方法是传递一个变量的地址,称为通过指针传递它。指针可能变得毛茸茸,常常让新程序员感到困惑,所以我会向你展示C ++机制:参考。
如上所述,当您使用参数调用函数时,C ++会创建一个新的本地范围变量,并将输入变量的值复制:
j
我们在这里看到&#39; 5&#39;是不是变量,而是硬编码值。没有任何办法可以解决这个问题。否则可能会起作用 - 整个计划&#39; 5&#39;本来会变成7。
当我们想说&#34;调用f并操作我的LOCAL变量&#34;我们使用参考。
void f(int n)
{
n += 2;
}
f(5);
很容易认为引用在某种程度上只是一个别名,但这并不是它们的实现方式。引用是一种巧妙的方法,可以在现有变量的内存中传递位置,但不够聪明,无法知道该变量消失或在内存中重新定位。
void f(int& n)
{
n += 2;
}
int main()
{
int x = 23;
f(x);
// x is now 25
}
关于引用要记住的另一件事是,一旦它们连接到某个东西,你就无法改变连接:
std::vector<int> v;
v.push_back(5);
int& first = v[0]; // reference to the first element of v at the moment,.
std::cout << "first = " << first << '\n'; // prints 5.
v.reserve(2000); // causes 'v' to relocate in memory
v[0] = 25;
std::cout << "first = " << first << '\n'; // may crash or print 5, but not 25.
这打印:566,而不是565,因为int a = 5, b = 6;
int& r = a;
std::cout << r;
r = b;
std::cout << r;
std::cout << a;
使int& r = a
引用了r
。当我们说a
时,因为r = b
现在是对r
的引用,我们有效地说a
。
----编辑2 ----
C和C ++有一个修饰符关键字a = b
,这是一个合同,表示你保证不会修改某个东西。如果你想编写一个通过引用接受复杂对象的函数(以避免复制字符串等,这是昂贵的),但你不想改变它,你可以使用const修饰符:
const
另外,关于&#39;&amp;&#39;的说明。编译器是否写#include <iostream>
#include <string>
void writeln(const std::string& str)
{
std::cout << str << '\n';
}
int main()
{
std::string greeting = "hello";
writeln(greeting);
}
或string& str
并不重要,它们的意思相同。 string &str
是否意味着&#39;引用&#39;或者&#39;地址(用于指针)或&#39;和&#39; (对于逻辑)取决于上下文。
答案 1 :(得分:-1)
注意:这些是在您发布样本输入和输出之前编写的。
将alpha
定义为
static const char alpha[] = {'D', 'L', 'P'};
它实际上是一个包含三个元素的char数组。但是strlen()
是在遇到第一个\0
(NUL)字符之前计算字符数的函数。因此strlen()
中的genRandom()
将无法正常工作(我猜它会返回一个随机的大数字。)您应该将alpha
定义为
static const char alpha[] = "DLP";
将隐含的第4个元素\0
添加到alpha
。
在您的pohyb()
中,您使用空的初始值定义string
varibales sD
,mD
和d
。它们与vector<int> d
中的vector<string> sD, mD
和main()
没有任何关系。因此,您的所有i < d.size()
,sD[i] == 'S'
,d[i] == 'D'
...都无法按预期工作。您应该将sD
中的mD
,d
和main()
作为参数传递给pohyb()
。
更新:好的我会更具体。由于string d
中的pohyb()
与vector<int> d
中的main()
无关,pohyb()
期间仍为空for (int i=0; i < d.size(); i++)
,因此int x[i], y[i]
不会运行一次。因为pohyb()
中的vector<int> x, y
与main()
中的i
无关,并且包含未初始化(=随机)i
元素(此处n
恰好相同调用pohyb()
到{{1}}时,您会看到奇怪的(“SPADOL”)输出。请先了解如何在C ++中将参数传递给函数。在你学习之前,你将无处可去。
我还没有检查这两个是否都是你需要的。它们只是我到目前为止发现的明显错误。您可能需要对程序结构进行基本的修改。