您如何看待代码? [英] What do you think about the code?

查看:58
本文介绍了您如何看待代码?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

你能对这段代码发表什么意见吗?

我用了一个goto,不好吗?


#include< stdio.h>

#include< stdlib.h>

#include< ctype.h>

#include< string.h>

#include< assert.h>


#define NOT_NULL 1

#define NUMERIC 2

#定义MULTI_LINE 4


/ *描述记录的一个字段* /

struct field_desc {

char * name;

int length;

int type;

};


#define FIELD_PROMPT"%s( %d):


结构记录{

size_t count;

struct field_desc * desc;

char **条目;

};


struct field_desc movies_desc [] = {

{" id" ,13,N​​OT_NULL | NUMERIC},

{" title",50,NOT_NULL},

{" genre",15,NOT_NULL},

{ length,3,NOT_NULL | NUMERIC},

{" description",65535,MULTI_LINE},

{" owner",10,NOT_NULL},

{ 可用,1,NOT_NULL | NUMERIC},

{" customer",30,0}};


#define MOVIES_LENGTH(sizeof(movies_desc)/ sizeof(movies_desc [0] ))


char * readl(size_t length,int multiline,char stop)

{

const size_t bufsize = 32;

int c,lastc;

size_t index;

size_t size;

char * str,* tmp;


size = 0;

str = NULL;


if(multiline)

lastc =''\ n'';

else

lastc = 0;


index = 0;

while((c = getchar())!= EOF&& index< length){

if(index + 1> = size){

size + = bufsize;

if(size> length + 1)

size = length + 1;


tmp = realloc(str,size);

if(tmp == NULL){

if(str)

免费(str);

返回NULL;

}

str = tmp;

}


/ *只有在multil时才会为真ine * /

if(c == stop&& lastc ==''\ n''){

if(stop ==''\ n'')

break;

if((c = getchar())==''\ n''|| c == EOF)

break;

else {

ungetc(c,stdin);

c =停止;

}

}

如果( c ==''\ n''&&!multiline)

break;


断言(索引+ 1< size);

str [index ++] = c;

lastc = c;

}

if(c == EOF& ;& index == 0)

返回NULL;


断言(str!= NULL);

断言(索引) < size);

str [index] =''\''';


/ *删除尾随''\ n'的(仅限多行)* /

if(index!= 0&& lastc ==''\ n'')

str [index - 1] = ''\''';


/ *删除该行上剩余的字符。 * /

while(c!=''\ n''&& c!= EOF)

c = getchar();


返回str;

}


/ *此函数假设粘性eof。这意味着,

*如果遇到EOF,将在下次调用此函数时再次从getchar()读取
*。 * /

char * read_multiline(size_t length)

{

return readl(length,1,''\ n'');

}


/ *读取一行最大长度并丢弃额外的

*字符。用于交互式使用* /

char * read_line(size_t length)

{

返回readl(长度,0,0);

}


int isnumeric(const char * str)

{

if(!str)

返回0;

而(* str){

if(!isdigit(* str)&& * str!='' \ n'')

返回0;

str ++;

}

返回1;

}


static int validate_entry(const char * entry,struct field_desc desc)

{

if( (desc.type& NUMERIC)&&!isnumeric(entry)){

fprintf(stderr,错误:值必须是数字\ n);

返回-1;

}

if((desc.type& NOT_NULL)&& entry [0] ==''\ 0' '){

fprintf(stderr,错误:值不能为null \ n);

返回-1;

}


返回0;

}


static void field_prompt(struc t field_desc desc)

{

printf(FIELD_PROMPT,desc.name,desc.length);

fflush(stdout);

}


static int get_field(char ** entry,struct field_desc desc)

{

if( desc.type& MULTI_LINE)

* entry = read_multiline(desc.length);

else

* entry = read_line(desc.length);


if(* entry == NULL)

返回EOF;


返回0;

}


int set_record_type(struct record * r,struct field_desc * desc,size_t

length)

{

size_t i;

r-> count = length;

r-> desc = desc;

r- > entries = malloc(length * sizeof(char *));

if(r-> entries == NULL)

返回-1;

/ *将所有数据初始化为NULL * /

for(i = 0; i< length; i ++)

r-> entries [i] = NULL;

返回0;

}


/ *用来自用户的输入填写记录* /

int fill_record(struct record r)

{

size_t i;

for(i = 0; i< r.count ; i ++){


field_prompt(r.desc [i]);

if(get_field(& r.entries [i],r.desc [i])== EOF)

go到atEOF;


while(validate_entry(r.entries [i],r.desc [i])!= 0){

free(r。条目[i]);

field_prompt(r.desc [i]);

if(get_field(& r.entries [i],r.desc [i ])== EOF)

转到atEOF;

}

}


返回0;


atEOF:

while(i--){

free(r.entries [i]);

r.entries [i] = NULL;

}

返回EOF;

}

void print_record(struct record r)

{

size_t i;

for(i = 0;我< r.count; i ++){

printf("%s:\"%s \" \ n",r.desc [i] .name,r.entries [i]);

}

}


void free_record(struct record r)

{

size_t i;


for(i = 0; i< r.count; i ++){

if(r.entries [i ])

免费(r.entries [i]);

}

免费(r.entries);

}


int main(无效)

{

struct record movies_record;


set_record_type(& movies_record,movies_desc,MOVIES_LENGTH);


fill_record(movies_record);


print_record(movies_record);


free_record(movies_record);


返回EXIT_SUCCESS;

}

解决方案

jaso写道:


你能否对这段代码发表任何评论?
我用了一个goto,是不是很糟糕?



这不是很糟糕。


- -

pete


你可以编写任何使用goto的代码,没有goto。


Goto不喜欢,因为它会导致难以阅读的代码。你应该尝试消除goto',因为它会让某人(除此之外)

能够编辑你的代码。

jaso写道:

你能否对这段代码发表任何评论?
我用了一个goto,是不是很糟糕?

#include< stdio.h>
#include< stdlib.h>
#include< ctype.h>
#include< string.h>
#include< assert.h>

#define NOT_NULL 1
#define NUMERIC 2
#define MULTI_LINE 4

/ *描述记录的一个字段* /
struct field_desc {
char * name;
int length;
int type;
};

#define FIELD_PROMPT"%s(%d):" <结构记录{
size_t count;
struct field_desc * desc;
char **条目;
};

结构field_desc movies_desc [] = {
{" id",13,N​​OT_NULL | NUMERIC},
{" title",50,NOT_NULL},
{" genre",15,NOT_NULL},
{" length",3,NOT_NULL | NUMERIC},
{" description",65535,MULTI_LINE},
{" owner",10,NOT_NULL},
{" available",1,NOT_NULL | NUMERIC},
{" customer",30,0}};

#define MOVIES_LENGTH(sizeof(movies_desc)/ sizeof(movies_desc [0]))

char * readl(size_t length,int multiline,char stop)
{
const size_t bufsize = 32;
int c,lastc;
size_t index;
size_t size;
char * str,* tmp;

size = 0;
str = NULL;

if(multiline)
lastc =''\ n'';
其他
lastc = 0;

index = 0;
while((c = getchar())!= EOF&& index< length){
if(index + 1> = size){
size + = bufsize;
if(size> length + 1)
size = length + 1;

tmp = realloc(str,size);
if(tmp == NULL){
if(str)
免费(str);
返回NULL;
}
str = tmp;
}
/ *只有在多行* /
if(c == stop&& lastc ==''\ n''){
if(stop ==''\ n'')
break;
if((c = getchar())== ''\ n''|| c == EOF)
休息;
其他{
ungetc(c,stdin);
c =停止;
}
}
if(c ==''\ n''&&!multiline)
break;

断言(index + 1< size );
str [index ++] = c;
lastc = c;
}
if(c == EOF&& index == 0)
返回NULL;

断言(str!= NULL);
断言(索引< size);
str [index] =''\ 0'';

/ *删除尾随''\ n'(仅限多行)* /
if(index!= 0&& lastc ==''\ n'')
str [index - 1] =''\ 0'';

/ *删除剩余的在线上的字符。 * /
while(c!=''\ n''&& c!= EOF)
c = getchar();

return str;
}

/ *此函数假定粘性eof。这意味着,
*如果遇到EOF,将在下次调用此函数时从getchar()再次读取它。 * /
char * read_multiline(size_t length)
{
返回readl(长度,1,''\ n'');
}
/ *读取一行最大长度并丢弃该行的其他
*字符。用于交互式使用* /
char * read_line(size_t length)
{
返回readl(长度,0,0);
}

int isnumeric(const char * str)
{
if(!str)
返回0;
while(* str){
if(!isdigit(* str) && * str!=''\ n'')
返回0;
str ++;
}
返回1;
}

static int validate_entry(const char * entry,struct field_desc desc)
{
if((desc.type& NUMERIC)&&!isnumeric(entry)){
fprintf(stderr,错误:值必须为数字\ n);
返回-1;
}
if((desc.type& NOT_NULL)&& entry [0] ==''\'''){
fprintf(stderr,错误:值不能为null \ n);
返回-1;
}

返回0;
}
静态void field_prompt(struct field_desc desc)
{
printf(FIELD_PROMPT,desc.name,desc.length);
fflush(stdout);
}

static int get_field(char * * entry,struct field_desc desc)
{
if(desc.type& MULTI_LINE)
* entry = read_multiline(desc.length);

* entry = read_line(desc.length);

if(* entry == NULL )
返回EOF;

返回0;
}
int set_record_type(struct record * r,struct field_desc * desc,size_t
长度)
{
size_t i;
r-> count = length;
r-> desc = desc;
r-> entries = malloc( length * sizeof(char *));
if(r->条目== NULL)
返回-1;
/ *初始化所有数据为NULL * /
(i = 0; i< length; i ++)
r-> entries [i] = NULL;
返回0;
}

/ *填充用来自用户的输入记录* /
int fill_record(struct record r)
{
size_t i;
for(i = 0; i< r.count; i ++){

field_prompt(r.desc [i]);
if(get_field(& r.entries [i],r.desc [i])== EOF)
转到atEOF;

while(validate_entry(r.entries [i],r.desc [i])!= 0){
免费(r.entries [i]);
field_prompt (r.desc [i]);
if(get_field(& r.entries [i],r.desc [i])== EOF)
转到atEOF;
} <返回0;

atEOF:
while(i--){
free(r.entries [i]);
r.entries [i] = NULL;
}
返回EOF;


void print_record(struct record r)
{
size_t i;
for(i = 0;我< r.count; i ++){
printf("%s:\"%s \" \ n",r.desc [i] .name,r.entries [i]);
}

void free_record(struct record r)
{
size_t i;

for(i = 0; i< r.count; i ++){
if(r.entries [i])
free(r.entries [i]);
}
free(r.entries);
}
int main(void)
结构记录movies_record;

set_record_type(& movies_record,movies_desc,MOVIES_LENGTH);

fill_record(movies_record);

print_record(movies_record);

free_record(movies_record);

返回EXIT_SUCCESS;
}




2006-06-23, mi ******** @ gmail.com < mi ******** @ gmail.com>写道:

你可以编写任何使用goto的代码,没有goto。

Goto不喜欢,因为它会导致代码难以阅读。你应该尝试消除goto',因为它会让某人(除此之外)能够编辑你的代码。




Don顶级帖子。我已经删除了你所引用的内容,因为它与你的观点无关。


更容易阅读:

/ *开始* /


而(测试[0])

而(测试[1])

而while(test [2])

{

if(test [3])

goto outOfLoop;

}


outOfLoop:

puts(从循环中逃脱。);

/ *结束* /


或者,没有转到:


/ *开始* /


int status = 0;


while(test [0])

{

while(test [1])

{

while(test [2])

{

if(test [3])

{

status = 1;

休息;

}

}

如果(状态)

休息;

}

如果(状态)

休息;

}


puts(从循环中逃脱。);


/ *结束* /

-

Andrew Poelst ra< http://www.wpsoftware.net/blog >

给我发电子邮件,请使用apoelstra。在上面的地址。

我知道那个小镇的区域就像我的脑袋一样。


Can you give any comments on this code?
I used one goto, is it bad?

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <assert.h>

#define NOT_NULL 1
#define NUMERIC 2
#define MULTI_LINE 4

/* Describes one field of a record */
struct field_desc {
char *name;
int length;
int type;
};

#define FIELD_PROMPT "%s (%d): "

struct record {
size_t count;
struct field_desc *desc;
char **entries;
};

struct field_desc movies_desc[] = {
{ "id", 13, NOT_NULL | NUMERIC },
{ "title", 50, NOT_NULL },
{ "genre", 15, NOT_NULL },
{ "length", 3, NOT_NULL | NUMERIC },
{ "description", 65535, MULTI_LINE },
{ "owner", 10, NOT_NULL },
{ "available", 1, NOT_NULL | NUMERIC },
{ "customer", 30, 0 } };

#define MOVIES_LENGTH (sizeof(movies_desc)/sizeof(movies_desc[0]))

char *readl(size_t length, int multiline, char stop)
{
const size_t bufsize = 32;
int c, lastc;
size_t index;
size_t size;
char *str, *tmp;

size = 0;
str = NULL;

if (multiline)
lastc = ''\n'';
else
lastc = 0;

index = 0;
while ((c = getchar()) != EOF && index < length) {
if (index + 1 >= size) {
size += bufsize;
if (size > length + 1)
size = length + 1;

tmp = realloc(str, size);
if (tmp == NULL) {
if (str)
free(str);
return NULL;
}
str = tmp;
}

/* Will only be true if multiline */
if (c == stop && lastc == ''\n'') {
if (stop == ''\n'')
break;
if ((c = getchar()) == ''\n'' || c == EOF)
break;
else {
ungetc(c, stdin);
c = stop;
}
}
if (c == ''\n'' && !multiline)
break;

assert(index + 1 < size);
str[index++] = c;
lastc = c;
}
if (c == EOF && index == 0)
return NULL;

assert(str != NULL);
assert(index < size);
str[index] = ''\0'';

/* Remove trailing ''\n''s (multiline only) */
if (index != 0 && lastc == ''\n'')
str[index - 1] = ''\0'';

/* Remove remaining characters on the line. */
while(c != ''\n'' && c != EOF)
c = getchar();

return str;
}

/* This function assumes sticky eof. That means,
* if an EOF is encountered, it will be read again
* from getchar() at the next call to this function. */
char *read_multiline(size_t length)
{
return readl(length, 1, ''\n'');
}

/* Reads one line of max length and discards additional
* characters on the line. Intended for interactive use */
char *read_line(size_t length)
{
return readl(length, 0, 0);
}

int isnumeric(const char *str)
{
if (!str)
return 0;
while (*str) {
if (!isdigit(*str) && *str != ''\n'')
return 0;
str++;
}
return 1;
}

static int validate_entry(const char *entry, struct field_desc desc)
{
if ((desc.type & NUMERIC) && !isnumeric(entry)) {
fprintf(stderr, "Error: Value must be numeric\n");
return -1;
}
if ((desc.type & NOT_NULL) && entry[0] == ''\0'') {
fprintf(stderr, "Error: Value must not be null\n");
return -1;
}

return 0;
}

static void field_prompt(struct field_desc desc)
{
printf(FIELD_PROMPT, desc.name, desc.length);
fflush(stdout);
}

static int get_field(char **entry, struct field_desc desc)
{
if (desc.type & MULTI_LINE)
*entry = read_multiline(desc.length);
else
*entry = read_line(desc.length);

if (*entry == NULL)
return EOF;

return 0;
}

int set_record_type(struct record *r, struct field_desc *desc, size_t
length)
{
size_t i;
r->count = length;
r->desc = desc;
r->entries = malloc(length * sizeof(char *));
if (r->entries == NULL)
return -1;
/* Init all data to NULL */
for (i = 0; i < length; i++)
r->entries[i] = NULL;
return 0;
}

/* Fills record with input from user */
int fill_record(struct record r)
{
size_t i;
for (i = 0; i < r.count; i++) {

field_prompt(r.desc[i]);
if (get_field(&r.entries[i], r.desc[i]) == EOF)
goto atEOF;

while (validate_entry(r.entries[i], r.desc[i]) != 0) {
free(r.entries[i]);
field_prompt(r.desc[i]);
if (get_field(&r.entries[i], r.desc[i]) == EOF)
goto atEOF;
}
}

return 0;

atEOF:
while (i--) {
free(r.entries[i]);
r.entries[i] = NULL;
}
return EOF;
}

void print_record(struct record r)
{
size_t i;
for (i = 0; i < r.count; i++) {
printf("%s:\"%s\"\n", r.desc[i].name, r.entries[i]);
}
}

void free_record(struct record r)
{
size_t i;

for (i = 0; i < r.count; i++) {
if (r.entries[i])
free(r.entries[i]);
}
free(r.entries);
}

int main(void)
{
struct record movies_record;

set_record_type(&movies_record, movies_desc, MOVIES_LENGTH);

fill_record(movies_record);

print_record(movies_record);

free_record(movies_record);

return EXIT_SUCCESS;
}

解决方案

jaso wrote:


Can you give any comments on this code?
I used one goto, is it bad?



It''s not very bad.

--
pete


you can write any code that uses a goto, without a goto.

Goto is disliked, as it leads to code that is harder to read. You
should try to eliminate goto''s as it will make somebody(other then you)
able to edit your code.
jaso wrote:

Can you give any comments on this code?
I used one goto, is it bad?

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <assert.h>

#define NOT_NULL 1
#define NUMERIC 2
#define MULTI_LINE 4

/* Describes one field of a record */
struct field_desc {
char *name;
int length;
int type;
};

#define FIELD_PROMPT "%s (%d): "

struct record {
size_t count;
struct field_desc *desc;
char **entries;
};

struct field_desc movies_desc[] = {
{ "id", 13, NOT_NULL | NUMERIC },
{ "title", 50, NOT_NULL },
{ "genre", 15, NOT_NULL },
{ "length", 3, NOT_NULL | NUMERIC },
{ "description", 65535, MULTI_LINE },
{ "owner", 10, NOT_NULL },
{ "available", 1, NOT_NULL | NUMERIC },
{ "customer", 30, 0 } };

#define MOVIES_LENGTH (sizeof(movies_desc)/sizeof(movies_desc[0]))

char *readl(size_t length, int multiline, char stop)
{
const size_t bufsize = 32;
int c, lastc;
size_t index;
size_t size;
char *str, *tmp;

size = 0;
str = NULL;

if (multiline)
lastc = ''\n'';
else
lastc = 0;

index = 0;
while ((c = getchar()) != EOF && index < length) {
if (index + 1 >= size) {
size += bufsize;
if (size > length + 1)
size = length + 1;

tmp = realloc(str, size);
if (tmp == NULL) {
if (str)
free(str);
return NULL;
}
str = tmp;
}

/* Will only be true if multiline */
if (c == stop && lastc == ''\n'') {
if (stop == ''\n'')
break;
if ((c = getchar()) == ''\n'' || c == EOF)
break;
else {
ungetc(c, stdin);
c = stop;
}
}
if (c == ''\n'' && !multiline)
break;

assert(index + 1 < size);
str[index++] = c;
lastc = c;
}
if (c == EOF && index == 0)
return NULL;

assert(str != NULL);
assert(index < size);
str[index] = ''\0'';

/* Remove trailing ''\n''s (multiline only) */
if (index != 0 && lastc == ''\n'')
str[index - 1] = ''\0'';

/* Remove remaining characters on the line. */
while(c != ''\n'' && c != EOF)
c = getchar();

return str;
}

/* This function assumes sticky eof. That means,
* if an EOF is encountered, it will be read again
* from getchar() at the next call to this function. */
char *read_multiline(size_t length)
{
return readl(length, 1, ''\n'');
}

/* Reads one line of max length and discards additional
* characters on the line. Intended for interactive use */
char *read_line(size_t length)
{
return readl(length, 0, 0);
}

int isnumeric(const char *str)
{
if (!str)
return 0;
while (*str) {
if (!isdigit(*str) && *str != ''\n'')
return 0;
str++;
}
return 1;
}

static int validate_entry(const char *entry, struct field_desc desc)
{
if ((desc.type & NUMERIC) && !isnumeric(entry)) {
fprintf(stderr, "Error: Value must be numeric\n");
return -1;
}
if ((desc.type & NOT_NULL) && entry[0] == ''\0'') {
fprintf(stderr, "Error: Value must not be null\n");
return -1;
}

return 0;
}

static void field_prompt(struct field_desc desc)
{
printf(FIELD_PROMPT, desc.name, desc.length);
fflush(stdout);
}

static int get_field(char **entry, struct field_desc desc)
{
if (desc.type & MULTI_LINE)
*entry = read_multiline(desc.length);
else
*entry = read_line(desc.length);

if (*entry == NULL)
return EOF;

return 0;
}

int set_record_type(struct record *r, struct field_desc *desc, size_t
length)
{
size_t i;
r->count = length;
r->desc = desc;
r->entries = malloc(length * sizeof(char *));
if (r->entries == NULL)
return -1;
/* Init all data to NULL */
for (i = 0; i < length; i++)
r->entries[i] = NULL;
return 0;
}

/* Fills record with input from user */
int fill_record(struct record r)
{
size_t i;
for (i = 0; i < r.count; i++) {

field_prompt(r.desc[i]);
if (get_field(&r.entries[i], r.desc[i]) == EOF)
goto atEOF;

while (validate_entry(r.entries[i], r.desc[i]) != 0) {
free(r.entries[i]);
field_prompt(r.desc[i]);
if (get_field(&r.entries[i], r.desc[i]) == EOF)
goto atEOF;
}
}

return 0;

atEOF:
while (i--) {
free(r.entries[i]);
r.entries[i] = NULL;
}
return EOF;
}

void print_record(struct record r)
{
size_t i;
for (i = 0; i < r.count; i++) {
printf("%s:\"%s\"\n", r.desc[i].name, r.entries[i]);
}
}

void free_record(struct record r)
{
size_t i;

for (i = 0; i < r.count; i++) {
if (r.entries[i])
free(r.entries[i]);
}
free(r.entries);
}

int main(void)
{
struct record movies_record;

set_record_type(&movies_record, movies_desc, MOVIES_LENGTH);

fill_record(movies_record);

print_record(movies_record);

free_record(movies_record);

return EXIT_SUCCESS;
}




On 2006-06-23, mi********@gmail.com <mi********@gmail.com> wrote:

you can write any code that uses a goto, without a goto.

Goto is disliked, as it leads to code that is harder to read. You
should try to eliminate goto''s as it will make somebody(other then you)
able to edit your code.



Don''t top-post. I''ve eliminated what you quoted because it isn''t really
relevant to your point.

What is easier to read:
/* Start */

while (test[0])
while (test[1])
while (test[2])
{
if (test[3])
goto outOfLoop;
}

outOfLoop:
puts ("Escaped from loop.");
/* End */

Or, without goto:

/* Start */

int status = 0;

while (test[0])
{
while (test[1])
{
while (test[2])
{
if (test[3])
{
status = 1;
break;
}
}
if (status)
break;
}
if (status)
break;
}

puts ("Escaped from loop.");

/* End */

--
Andrew Poelstra < http://www.wpsoftware.net/blog >
To email me, use "apoelstra" at the above address.
I know that area of town like the back of my head.


这篇关于您如何看待代码?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆