(및 배열)의 크기는 얼마나 됩니까?
다음 질문을 따릅니다.어레이의 주소가 C의 값과 동일한 이유는 무엇입니까?
#include <stdio.h>
#define N 10
char str2[N]={"Hello"};
int main(){
printf("sizeof(str2): %d bytes\n", sizeof(str2));
printf("sizeof(&str2): %d bytes\n", sizeof(&str2));
return 0;
}
출력:
sizeof(str2): 10 bytes
sizeof(&str2): 4 bytes
나는 그것을 알고 있습니다.str2alone은 배열된 첫번째 요소의 주소입니다.str2. 그리고 언제str2의 논쟁입니다.sizeof전체 배열 str2의 크기를 반환합니다.
외에 .&str2또한 arr의 첫번째 요소의 주소입니다.str2유형이 다릅니다(char (*)[N]== pointer to array).그런데 어떻게.&str2의 논쟁일 때는 행동합니다sizeof?
사이의 차이&str그리고.str,언제str로 선언됩니다.char str[10]?
연산자 읽기:
6.5.3.4 , 1125:
때 바를 때.sizeofoperator to array type의 결과는 배열의 총 바이트 수입니다.
그래서, 당신의 선언에 의하면,sizeof(str2)는 10바이트의 전체 배열 크기를 제공합니다(N은 10으로 정의되고 문자 크기는 1바이트이기 때문입니다).
반면에 표현에 있어서는sizeof(&str2),&str2는 배열의 주소이며 해당 주소의 크기는 시스템에서 4바이트입니다.(일부 시스템에서는 주소 크기가 8바이트(예: 64비트)일 수 있습니다.)
외에 .
&str2또한 arr의 첫번째 요소의 주소입니다.str2?
아니요, 값 단위로 둘 다&str2그리고.str동일하지만 의미론적으로 둘 다 다릅니다.하나는 10자 배열의 주소이고 다른 하나는 1자 배열의 주소입니다.
그들 사이에 있는 자신의 예에서 본 한 가지 차이점은 (@ouah가 이것을 대답으로 설명했다)입니다.
- 유형의
str이다.char[10] - 유형의
&str이다.char(*)[10]
둘째: 다이어그램을 따르는 것이 다른 차이를 관찰하는 데 도움이 됩니다.
for declaration:
#define N 10
char str2[N] = {"Hello"};
str2 Array in memory is something like:
----------------------------------------
str
+----+----+----+----+----+----+----+----+----+----++----+
|'H' |'e' |'l' |'l' |'o' |'\0'|'\0'|'\0'|'\0'|'\0'|| '@'|
+----+----+----+----+----+----+----+----+----+----++----+
201 202 203 204 205 206 207 208 209 210 211
▲ ▲ ▲ ▲
| | | |
|(str2) (str2 + 1) |
| |
|-----------------------------------------------------|
|201 |
| |
| |
(&str2) = 201 (&str2 + 1) = 211
* assuming str address start from 201
* str[N] is 10 char long 201-210, partially initialized
* at uninitialized position, str2[i] = '\0'
* location 211 is unallocated, having garbage value,
access to this location is illegal-Undefined Behavior
위 다이어그램에 대해 다음과 같은 코드를 작성할 수 있습니다.
#include <stdio.h>
#define N 10
int main(){
char str2[N]={"Hello"};
printf("\n %p, %p\n",str2, str2+1);
printf("\n %p, %p\n",(&str2), (&str2+1));
}
출력:
0xbf67e142, 0xbf67e143
0xbf67e142, 0xbf67e14c
첫 번째 줄에서는 출력 주소가 1바이트 차이가 나지만, 두 번째 줄에서는 배열의 포인터이기 때문에 10바이트 차이가 납니다(위의 다이어그램에 나와 있음).
포인터 산술의 규칙에 따르면 포인터 변수에 1을 추가하면 해당 변수는 자신의 유형의 다음 요소를 가리키기 시작합니다.그래서 10바이트 차이가 나는 이유는&str2는 배열을 가리키는 주소입니다.
세 번째 차이:
함으로써*str2첫번째 요소에 접근할 수 있습니다.반면에.*(&str2)첫번째 요소를 제공하지 않으며, 대신 첫번째 요소의 주소를 제공합니다.
여기에는 다음과 같은 예가 도움이 됩니다.
#include <stdio.h>
#define N 10
int main(){
char str2[N]={"Hello"};
printf("\n%p %c, %p %c\n",str2, *(str2), *(&str2), **(&str2));
}
출력:
0xbf587046 H, 0xbf587046 H
출력중
str2 gives 0xbf587046
*(str2) H
*(&str2) 0xbf587046
**(&str2) H
은 .*(&str2) == str2값은 주소입니다.서.*(str2) = **(&str2)ㅇH.
편집: 위에서 다음과 같은 차이점을 나타냈습니다.&str그리고.str어디에str는 유형의 배열입니다.char[10].
사이의 차이char *str그리고.char str[]그리고 둘 다 기억 속에 어떻게 저장되어 있는지.
다음과 같은 두 가지 선언이 있다고 가정합니다.
char *str1 = "hello";
char str2[] = "hello";
위 선언문에서str1에 대한 포인터입니다.char, (첫 번째 문자의 주소를 보유함으로써) 일정한 문자열 리터럴을 가리킵니다.h인에"hello"문자열).
C에 있는 문자열은 다음과 같습니다.char[N](배열) 유형이 그 이유입니다.sizeof("hello")6을 주는 이유는"hello"문자열은 6자 길이 배열(\0은 null,료, helloochar[6]).
당신을 추모합니다."hello"문자열은 다음과 같이 저장됩니다.
str1 23 24 25 26 27 28
+----+ +----+----+----+----+----+----+
| 23 | | h | e | l | l | o | \0 |
+----+ +----+----+----+----+----+----+
+-----------▲
here the address of the hello string is the first address = 23.
str1: is a pointer capable of storing an address.
"hello" consists of 6 chars
char* str1 = "hello";기본적으로 문자열 hello의 주소를 포인터 변수에 저장합니다.str1위 그림에서 보는 바와 같이
참고: 원하는 경우 변경할 수 있습니다.str1다른 끈을 가리키기 위해서요하지만 수정할 수 없습니다.hello끈을 매다 다음 가 유효합니다예를 들어 다음 코드가 유효합니다.
char* str1 = "hello"; // str1 points to hello str1-->"hello"
str1 = "world"; //Now, str1 points to world str1-->"world"
지금이다str1다른 일정한 문자열 세계를 가리킵니다.
str1 93 94 95 96 97 98
+----+ +----+----+----+----+----+----+
| 93 | | w | o | r | l | d | \0 |
+----+ +----+----+----+----+----+----+
+-----------▲
here address of world string is first address = 93.
str1: value change to point string world.
유의할 사항:str1일정한 문자열을 가리키므로 액세스/메모리 위치를 indexing하여 문자열을 수정할 수 없습니다.str1[i] = 'A'; 읽기 전용 메모리에 글을 쓰고 있기 때문에 불법이며 런타임에 이 동작이 정의되지 않습니다(구사적으로 정확하므로 컴파일 오류는 없음).
다시 한 번 말씀드리str1포인터입니다.sizeof(str1)같은 기계에 4개를 줄 겁니다.
나의 다음 코드와 실행:
#include <stdio.h>
int main(){
char* str1="Hello";
printf("\nstr1: %s, address: %p, sizeof(str1): %u", str1, str1, sizeof(str1));
str1 = "world";
printf("\nstr1: %s, address: %p, sizeof(str1): %u", str1, str1, sizeof(str1));
return 1;
}
출력:
str1: Hello, address: 0x80485e8, sizeof(str1): 4
str1: world, address: 0x8048619, sizeof(str1): 4
그래서 새로운 문자열을 지정하기 위해서는 단순히 새로운 문자열의 주소를 지정합니다.하지만 전화를 할 수 없습니다.strcpy()그것은 읽기 전용 메모리 위치에 쓰려 할 것이며 불법입니다.
두번째 선언에서char str2[] = "hello";,str2[]입니다.\0종료된 문자 배열(또는 문자열)이지만 포인터는 아닙니다.이 선언 크기에는 기본 크기가 주어지지 않으므로 상수 문자열 "hello"의 크기가 6임을 알 수 있습니다.유형str2이다.char[6].
우리가 할때는char str2[] = "hello";char 배열이 생성되고 hello 문자열이 해당 배열에 복사됩니다. 그래서.str2는 단순히 포인터가 아니라 완전한 문자열을 저장하는 배열입니다.
개념적으로.
str2:
103 104 105 106 107 108
+----+----+----+----+----+----+
| h | e | l | l | o | \0 |
+----+----+----+----+----+----+
이 경우 코드에서 할 수 없습니다.str2[] = "world";아니면str2 = "world", 컴파일 타임 에러가 될 것입니다.
예제 코드:
#include<stdio.h>
int main(){
char str2[] = "hello";
str2[] = "world";
str2 = "world";
return 1;
}
컴파일 오류:
In function 'main':
Line 4: error: expected expression before ']' token
Line 5: error: incompatible types in assignment
이 배열 위치str2를 들어다를 등 할 수 . 예를 들어 내용을 수정할 수 있습니다.str2[2] = 'A'완벽하게 유효합니다.strcpy를 호출하여 내용을 변경할 수도 있습니다(주소 공간은 변경되지 않습니다).
strcpy(str2, "world");
str2:
103 104 105 106 107 108
+----+----+----+----+----+----+
| w | o | r | l | d | \0 |
+----+----+----+----+----+----+
Note that when "world" is copied into a same memory space, the addresses of both "world" and "hello"
string are the same.
코드 예제:
#include<stdio.h>
int main(){
char str2[] = "hello";
printf("\nstr2: %s, address: %p, sizeof(str2): %u", str2, str2, sizeof(str2));
str2[2] = 'A';
printf("\nstr2: %s, address: %p, sizeof(str2): %u", str2, str2, sizeof(str2));
strcpy(str2, "world");
printf("\nstr2: %s, address: %p, sizeof(str2): %u", str2, str2, sizeof(str2));
return 1;
}
출력:
str2: hello, address: 0xbf58d056, sizeof(str2): 6
str2: heAlo, address: 0xbf58d056, sizeof(str2): 6
str2: world, address: 0xbf58d056, sizeof(str2): 6
참고: 동일한 주소 공간에서 문자열 값이 다릅니다.sizeof(str2)= 6은 배열 크기(바이트 단위)인 기존 답변에서 완벽하게 이해할 수 있습니다.
2차원 배열에 대한 유사한 설명을 읽으려면 메모리에 와 와 와 둘 다 저장되는 방법의 차이를 읽어 보십시오.
&str2포인터입니다.따라서 플랫폼에서 포인터의 크기만 확인할 수 있습니다.
str2유형의char [10]즉, array)10 of
&str2유형의char (*)[10](즉, 배열에 대한 포인터)10char).
그렇게sizeof (&str2)포인터 유형의 객체 크기를 산출합니다.char (*)[10]
단순히 변수를 사용하는 경우arr(정의대로)char arr[10]), 항상 상수 포인터로 붕괴합니다.char *const arr첫 번째 요소를 가리킵니다.하는 동안에&arr포인터로 연결됩니다.char (*)[10]의 크기를 포함합니다.arr, 예를 들면10.
언급URL : https://stackoverflow.com/questions/15177420/what-does-sizeofarray-return
'programing' 카테고리의 다른 글
| 도메인 간 게시물로 자격 증명을 보내시겠습니까? (0) | 2023.10.27 |
|---|---|
| Git: 커밋을 리버스 병합하는 방법? (0) | 2023.10.27 |
| 쓰기가 버퍼에 지속적으로 4K 바이트를 남기는 이유는 무엇입니까? (0) | 2023.10.27 |
| RxJS - 오류가 발생하면 관측 가능이 완료되지 않습니다. (0) | 2023.10.27 |
| 시작 작업의 스크립트 블록에 제기된 예외를 캡처하는 방법은? (0) | 2023.10.27 |