무의식적으로 쓰는 arg에서 argv[] 뭐가 다른가요?

mywin의 이미지

보통

int main(int argc, char** argv) {
    //statement
}

이런 식으로 argv를 언급합니다. argv에 전달되는 문자열들을 받기 위해서 이중포인터를 사용하는 것이죠. 그런데

int main(int argc, char* const argv[]) {
    //statement
}

라고 언급하기도 하는데요. 저 둘의 차이는 뭔가요. 후자는 문자열이 변경불가능한 상수라는 의미인 것 같은데요. 이 후자가 이렇게도 사용될 수 있는 것 아닌가요?

int main(int argc, char* const* argv) {
    //statement
}

이거 문법상 맞는지 모르겠네요. 일반적인 포인터처럼 해석해보면 되겠죠? 첫 번째 것은 포인터의 포인터인데다 const가 아니니 argv에 다른 이중포인터를 대입하는 것도 가능할 것이고, argv[0], argv[1]... 등등에 단일포인터의 대입도 가능할 것이며, 심지어 그 대상체의 값도 변경 가능하다는 이야기죠? 이런 식으로 분석해나가면 되는 것인지요? 무심코 썼던 arg에 대해 질문올립니다.

HDNua의 이미지

일단 말씀하신 것처럼 argv에 다른 이중 포인터를 대입해보시고,
argv[0], argv[1], ...에 단일 포인터를 대입해보시고,
그렇게 대입이 성공한다면 해당 변수의 값을 바꿔보세요.

tune***라고 자기가 아무 것도 안 해보고 질문하던 분이 떠올라 적어봅니다. 악의는 없구요.

저는 이렇게 생각했습니다.

익명 사용자의 이미지

여러가지 주제가 복합적으로 얽힌 질문이로군요.

1. 선언이 복잡한 두 데이터형에서, 중간에 const가 포함되거나 포함되지 않았을 때 상호 호환 여부
설명하자면 긴데, 두 데이터형을 영어로 썼을때, 맨 앞에 const가 있는 데이터형은 없는 데이터형과 호환됩니다. 그러나 그 외의 위치에서 차이가 난다면 서로 호환되지 않습니다. 질문하신 첫번째 예와 두번째 예는 서로 호환되지만 세번째 예와는 호환되지 않습니다. 컴파일해 보시고 에러나 경고 메시지 확인해보세요.
이 문제는 특히 C++에서 템플릿이나 다형성하고 얽히면 매우 해결하기 까다로운 문제가 됩니다.

2. 함수 매개변수 선언부에서, array가 pointer로 자동 변환됨.
이 기묘한 규칙 때문에 C언어에서는 함수가 배열만큼은 직접 넘겨받지 못합니다. C에서는 함수의 매개변수가 복사를 통해 함수 내부로 전달되는데, 오로지 배열만이 이 규칙때문에 마치 원본이 그대로 전달되는듯이 행동합니다. 하지만 함수 내부에서 sizeof 연산자를 넘겨받은 배열에 대해 사용하면 바로 그 본색을 드러내는데...
역시 최대한 짧게 설명하자면, 함수 매개변수의 데이터형을 영어로 쓴 다음, 가장 맨앞에 array가 온다면 그건은 pointer로 자동 치환됩니다. 그러나 중간에 낀 array에는 이 규칙이 적용되지 않습니다.
그래서 main 함수 써줄때 char **argv나 char *argv[]나 상관없는 겁니다. 하지만 char (*argv)[]나 char argv[][]같은건 안되죠.

cinsk의 이미지

참고로, int main(int argc, char* const argv[])는 바람직하지 않습니다. argv는 변경할 수 있도록 되어 있습니다.

int main(int argc, char *argv[]) { ... }
 
// 또는
 
int main(int argc, char **argv) { ... }

를 쓰세요.

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.