C 如何使用指针数组输出通过随机片段配置的序列
我对编码还不熟悉,我们只是在学习指针,我不确定为什么这段代码不能在整个程序中将句子的位存储到句子数组中,或者为什么它不能打印数据 这是一个学校作业,我通常只是花几个小时尝试不同的方法,但我想最好是征求意见,这样我才能学会正确地做这件事C 如何使用指针数组输出通过随机片段配置的序列,c,C,我对编码还不熟悉,我们只是在学习指针,我不确定为什么这段代码不能在整个程序中将句子的位存储到句子数组中,或者为什么它不能打印数据 这是一个学校作业,我通常只是花几个小时尝试不同的方法,但我想最好是征求意见,这样我才能学会正确地做这件事 #include "stdio.h" #include "stdlib.h" #include "time.h" #include "string.h" #define SIZE 4
#include "stdio.h"
#include "stdlib.h"
#include "time.h"
#include "string.h"
#define SIZE 4
void nounPick(const const char *nPTR, char *sPTR );
void verbPick(const const char *vPTR, char *sPTR );
void prepPick(const const char *pPTR, char *sPTR );
void artiPick(const const char *aPTR, char *sPTR );
int main(void){
char *noun[SIZE];
char *verb[SIZE];
char *prep[SIZE];
char *arti[SIZE];
char *sent[SIZE];
noun[0] = "cat ";
noun[1] = "dog ";
noun[2] = "truck ";
noun[3] = "plane ";
noun[4] = "skateboard ";
verb[0] = "drove ";
verb[1] = "jumped ";
verb[2] = "ran ";
verb[3] = "walked ";
verb[4] = "flew ";
prep[0] = "to ";
prep[1] = "from ";
prep[2] = "over ";
prep[3] = "under ";
prep[4] = "on ";
arti[0] = "a ";
arti[1] = "one ";
arti[2] = "some ";
arti[3] = "any ";
const char *nPTR = noun[0];
const char *vPTR = verb[0];
const char *pPTR = prep[0];
const char *aPTR = arti[0];
char *sPTR = sent[0];
srand( time(NULL));
for(int c = 0; c< SIZE; c++)
*(sent + c) = 0;
nounPick(nPTR, sPTR);
verbPick(vPTR, sPTR);
prepPick(pPTR, sPTR);
artiPick(aPTR, sPTR);
printf("Made it through the picking\n");
printf("Your Random Sentence Is As Follows:\n");
for(int i = 0; i < SIZE; i++){
if(*(sent + i) == 0)
i = SIZE;
else
printf("%s", *(sent + i));
}
return 0;
}
void nounPick(const const char *nPTR, char *sPTR ){
int i = 0;
int l = rand() % 5;
printf("%d, is L\n", l);
do{
switch(*(sPTR + i)){
case 0:
*(sPTR + i) = *(nPTR + l);
break;
default:
i++;
break;
}
} while (i < SIZE);
}
void verbPick(const const char *vPTR, char *sPTR ){
int i = 0;
int l = rand() % 5;
printf("%d, is L\n", l);
do{
switch(*(sPTR + i)){
case 0:
*(sPTR + i) = *(vPTR + l);
break;
default:
i++;
break;
}
} while (i < SIZE);
}
void prepPick(const const char *pPTR, char *sPTR ){
int i = 0;
int l = rand() % 5;
printf("%d, is L\n", l);
do{
switch(*(sPTR + i)){
case 0:
*(sPTR + i) = *(pPTR + l);
break;
default:
i++;
break;
}
} while (i < SIZE);
printf("\n\n%s\n\n", sPTR);
}
void artiPick(const const char *aPTR, char *sPTR ){
int i = 0;
int l = rand() % 5;
printf("%d, is L\n", l);
do{
switch(*(sPTR + i)){
case 0:
*(sPTR + i) = *(aPTR + l);
break;
default:
i++;
break;
}
} while (i < SIZE);
}
#包括“stdio.h”
#包括“stdlib.h”
#包括“time.h”
#包括“string.h”
#定义大小4
void nounPick(const const char*nPTR,char*sPTR);
void verbPick(常量const char*vPTR,char*sPTR);
void prepick(const const char*pPTR,char*sPTR);
void artiPick(const const char*aPTR,char*sPTR);
内部主(空){
字符*名词[大小];
字符*动词[大小];
字符*prep[大小];
字符*arti[大小];
字符*已发送[大小];
名词[0]=“猫”;
名词[1]=“狗”;
名词[2]=“卡车”;
名词[3]=“平面”;
名词[4]=“滑板”;
动词[0]=“驱动”;
动词[1]=“跳跃”;
动词[2]=“然”;
动词[3]=“行走”;
动词[4]=“fleed”;
准备[0]=“到”;
prep[1]=“from”;
准备[2]=“结束”;
prep[3]=“在下”;
准备[4]=“打开”;
arti[0]=“a”;
arti[1]=“一”;
arti[2]=“一些”;
arti[3]=“任何”;
常量char*nPTR=名词[0];
const char*vPTR=动词[0];
常量字符*pPTR=prep[0];
常量char*aPTR=arti[0];
char*sPTR=sent[0];
srand(时间(空));
对于(int c=0;c
在调试器中运行代码。它有多个缺陷:
地址:
sent
未初始化,然后将sPTR
传递给nounPick()
和其他函数,在这些函数中取消引用并使用未定义的结果访问它(在我的示例中,在Visual Studio的调试器中引发异常)
即使将初始化移动到分配sent的循环之后,行:
switch(*(sPTR + i)){
获取空指针,偏移它,然后取消引用它
老实说,除了识别这个问题(这可能只是第一个障碍)之外,解开这段代码的意图以及它是如何工作的可能是毫无意义的。让你的解决方案起作用太复杂了。其中有一些风格怪异的代码,可能是课程风格,也可能是为了演示指针操作而设计的(数组索引更合适)。在任何情况下,也存在设计拙劣或不明智的因素
我建议您将字符串数据封装在选择器函数中,并将其简化如下:
const char* nounPick()
{
static const char* noun[] = { "cat", "dog", "truck", "plane", "skateboard" } ;
int i = rand() % (sizeof(noun) / sizeof(*noun)) ;
return( noun[i] ) ; // or "noun + i" if that is the intent of the exercise
}
。。。对于其他选择器函数也是如此。这样,每个元素可以有不同的长度列表,每个选择器从初始化器的数量知道其列表的长度,而不是某个普通的SIZE
,这可能对所有数组都不正确(在您的情况下,除了arti
数组之外,不是所有数组都正确)
然后输出:
printf( "%s %s %s %s %s\n", artiPick(), nounPick(), verbPick(),
prepPick(), nounPick() ) ;
代码将更安全、更简单、更易于遵循。然而,它可能不满足分配要求,分配要求可能被设计为显示指针操作的特定方面。如果是这样的话,这是一种相当糟糕的教学方法-引入糟糕的编码风格来教授语言的某些方面是没有帮助的。使用不同的初始化和直接打印:
char *noun[] = {"cat", "dog", "truck", "plane", "skateboard" };
char *verb[] = {"drove", "jumped", "ran", "walked", "flew" };
char *prep[] = {"to", "from", "over", "under", "on" };
char *arti[] = {"a", "one", "some", "any"};
srand(time(0));
int i = 12;
while(--i >= 0)
printf("%s %s %s %s\n",
arti[rand() % 4],
noun[rand() % 5],
verb[rand() % 5],
prep[rand() % 5]);
每个类别的字数在%
操作中硬编码sizeof arti/sizeof*arti
将是如何取回它,如果您不知道并且没有将它存储为n_arti
例如,对于大小为10的数组中的6个名词,您将使用“6”,而不是分配的大小
除了printf
之外,还可以为char*句子[4]
赋值,比如句子[2]=动词[rand…]
。但这四个词也必须循环或展开
为了确保这是有意的,并且因为它很有趣,这里是输出:
any dog walked under
one cat jumped under
one truck walked from
a cat ran under
some dog jumped under
any skateboard walked over
some plane drove to
some skateboard ran from
some dog ran to
a dog ran on
one dog walked to
one cat walked from
#定义尺寸4
这应该是N_WORD_CATEG左右;它是由每个类别中的一个单词组成的句子数组的大小。any dog walked under
one cat jumped under
one truck walked from
a cat ran under
some dog jumped under
any skateboard walked over
some plane drove to
some skateboard ran from
some dog ran to
a dog ran on
one dog walked to
one cat walked from
printf("%s %s %s %s %s %s\n",
arti[rand() % 4],
noun[rand() % 5],
verb[rand() % 5],
prep[rand() % 5],
arti[rand() % 4],
noun[rand() % 5]);
some cat jumped to one cat
one skateboard walked on some dog
one plane flew under one skateboard