2017-10-16 9 views
3
#include <cs50.h> 
#include <stdio.h> 
#include <string.h> 

int main(void) 
{ 
    //ask user for input 
    string s = get_string(); 

    //make sure get_string() returned a string 
    if(s != NULL) 
    { 
     //iterate over the characters one at a time 
     for(int i = 0, int n = strlen(s); i < n; i++) 
     { 
      //print i'th character in s 
      printf("%c\n", s[i]); 
     } 
    } 
    else 
    { 
     //tell the user that their input is not a string 
     printf("Sorry, no good\n"); 
    } 

} 

컴파일러는이 라인에 대해 불평 :여러 유형 지정자

for(int i = 0, int n = strlen(s); i < n; i++) 

내가 유형을 정의하는 int와 정수 n을 선언하기 때문이다. 이 예에서 n에 대한 i에 대한

for(int i = 0, n = strlen(s); i < n; i++) 

int가 필요합니다/좋은 형태가 아니라 :

프로그램으로 잘 컴파일?

+0

[size \ _t와 int를 비교하는 것] 가능한 복제본 (https://stackoverflow.com/questions/3642010/comparing-int-with-size-t) – Eimantas

+4

'int i, n;' for-loop 또는 not)는 두 개의 변수를 선언합니다 (반면 int i, int n;은 올바르지 않습니다). 여기서 OP는 또한 그들을 초기화하는 일이 발생합니다. – TripeHound

+2

@Eimantas 전혀 없습니다. –

답변

9

그건이 줄 이유는

int i = 0, n = strlen(s) 

in라는 두 개의 정수를 만들고이를 초기화한다.

int i = 0, int n = strlen(s) 

당신은 i하고 초기화라는 int를 만든 다음 다른이 이해가되지 않습니다 int n라고하는 int 만들려고 :

당신은 넣어합니다.

어디서나 n을 초기화 할 이유가 없습니다. 변경해서는 안됩니다. 루프 전에 초기화 :

int n = strlen(s); 

for(int i = 0; i < n; i++) 
{ 
    ... 
+0

그건 나에게도 깨끗해 보이지만 교수가하는 방식은 내가 보여준 방식이다. – phindex

+1

교수는 거친 밤을 보냈 음에 틀림 없습니다. –

+0

@phindex 그리고 괜찮습니다. 당신이했던 질문에서했던대로 할 수 있습니다. – Steve

1

처음으로 int을 사용하면 모든 쉼표로 구분 된 변수가 이제 int가됩니다.

2 개 문은 다음과 같은 것을 의미 :

int a, b; //a = int, b = int 
int a; int b; //a = int, b = int 
4

라인 int i = 0, n = strlen(s)는 선언 목록입니다. 거기에 쉼표를 입력하면 "같은 유형의 다른 변수를 제공하십시오"라고 말합니다. 코드는 int x, y;과 동일합니다.

어떤 경우에는 같은 줄에 여러 변수를 선언하는 것은 위험 할 수 있습니다. 초기화 오해가있을 수 있으며 포인터 인 변수와 그렇지 않은 변수에 대한 오해가있을 수 있습니다. (int* x, y하지는 두 개의 포인터를 선언한다.)

따라서는 항상 선언에 자신의 라인에있는 모든 변수 좋습니다. 또한 가능한 한 깨끗하고 단순한 루프를 유지하는 것이 좋습니다. 그 루프를 작성하는 가장 좋은 방법은 그러므로이 될 수 있습니다

int n = strlen(s); 
for(int i = 0; i < n; i++) 
+0

부수적으로,이 경우 우리가하는 배열의 길이를 취할 때 가장 올바른 유형은 정수형'size_t'를 사용하는 것입니다. CS50에서 이것을 가르쳐주지는 않습니다. – Lundin

+0

"가장 올바른 유형"을 제외하고, 이것이'strlen'이 반환하는 것과 정확히 일치한다는 사실도 있습니다. 암시 적 변환을 피하는 것보다 다른 이유가 없다면'size_t'이어야합니다. – StoryTeller

+0

@ Lundin 왜 * CST는 size_t를 가르치지 않습니까? 내가해서는 안되는 어딘가를 배우고 있습니까? – phindex

1

C는 초기 유형 선언 이후에 여러 변수를 선언 할 수 있습니다 : 허용되지 않습니다

int x, y, z =0, whatever; 

목록에 추가 형 선언을 추가, 그것은 일치하는 경우에도 실물.

-2

strlen (연산자 sizeof 기준)의 반환 유형은 부호가없는 정수 유형의 별칭 인 인 size_t입니다. 따라서 유형 intsize_t 유형의 모든 값을 수용 할 수 없습니다.

따라서 int 유형 대신 size_t 유형을 사용하십시오.

또한 for 루프에 표시된 구문 오류가 있습니다.

선언 그래서 선언 지정자 식별자의 목록에있는 모든 선언 된 식별자 모든 선언자를 선행하여야한다

declaration: 
    declaration-specifiers init-declarator-listopt ; 
    static_assert-declaration 

같은 C 표준에 정의되어 있습니다. i 선언자 사이 n 선언 지정자 int이 발생하기 때문에

그래서 루프

int i = 0, int n = strlen(s); 

의이 선언이 올바르지 않습니다.

쓰기

for(size_t i = 0, n = strlen(s); i < n; i++) 

대신 사실

for(int i = 0, int n = strlen(s); i < n; i++) 

의 기능 strlen를 호출 할 필요가 없다. 루프는 루프없이 작성할 수 있습니다. 이 프로그램의 마지막에

string s = get_string(); 

처럼 선언 된 포인터 s을 확보해야하는

for(size_t i = 0; s[i] != '\0'; i++) 
    { 
     //print i'th character in s 
     printf("%c\n", s[i]); 
    } 

주의하십시오. 예를 들어

free(s); 
+0

도대체 어떻게이 포스트가 downwotes를 얻었습니까? – sp2danny

+1

@ sp2danny 러시아에 대한 제재 조치가 있습니까? :) –

0

당신은 이것을 시도하고 있습니다.

int i = 0, int n =strlen(s); 

괜찮습니다. , '에 대한'이전에 정의

int i = 0, n=strlen(s);//or 
/*-----------------*/ 
int n = strlen(s); 
for(int i = 0;....)//or 
/*-----------------*/ 
int i = 0;int n= strlen(s);//unnecessary but not wrong 

을 그리고 (...)에 대한에 무관 veriable를 정의하지 :

int i = 0 , char s ; 

당신은 사람들을 시도 할 필요가 동일합니다.

0

for(int i = 0, int n = strlen(s); i < n; i++){ /*...*/ }은 유효한 C/C++ 구문입니다. for(int i = 0, n = strlen(s); i < n; i++){ /*...*/ }입니다. 이렇게 할 수있는 것은 in이 같은 유형이어야한다는 것입니다. 당신이 그들을 다르게 입력 원한다면, 당신은 할 수있는 다음> = C99 for 루프보다 모두 더 유연하고 더 휴대용

{ int i=0; long n=strlen(s); for(; i<n; i++) { /*...*/ } } 

합니다.

+0

은 기존 답변에 아무 것도 추가하지 않습니다. – sp2danny