yes 일까, no 일까..

 

문자열 공부 중 책에 아래와 같은 코드가 있었다.

char* str1 = "you";
char* str2 = "me";

if(strlen(str2) - strlen(str1) >= 0 ) printf("yes\n");
else printf("no\n");

strlen(const char* string) 함수는 문자열의 길이를 반환한다.

strlen(str1) - strlen(str2)은 2-3 이므로 -1. 여기까지는 문제없다. 하지만 반환하는 데이터 타입이 unsigned 이다.

그래서 저 코드의 출력은 yes 이다.

 

부호가 없는 unsigned 끼리의 뺄셈에서 결과값도 음수가 아닌 양수로 나온다... unsigned 는 부호비트가 없으니 무조건 양수로 나와야겠지.. 그럼 어떻게? 이 계산은 모듈라 연산을 따른다.

 

stackoverflow 사이트에서 같은 내용이 있다. 아래 그림도 해당 사이트에서 가져왔다.

9시에서 4시간을 더하면 1시, 1시에서 4시간은 빼면 -3시가 아니라 9시다.

9 + 4 = 1 (13 % 12), 1 - 4 = 9 (-3 % 12)이다.

이 방법을 저 코드에 대입하면 다음과 같다. (2 - 3) % 2^32, 그리고 결괏값은 4,294,967,295이다.

 

앞에 3byte는 빼고 1바이트만 놓고 보자.

2 -> 0000 0000 0000 0000 0000 0000 0000 0010, 1을 빼면

1 -> 0000 0000 0000 0000 0000 0000 0000 0001, 1을 다시 빼면

0 -> 0000 0000 0000 0000 0000 0000 0000 0000, 1을 다시 또 빼면

-1 -> FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF 가 된다.

 

결괏값이 unsigned 이거나 unsigned 값끼리의 연산, 혹은 strlen과 같은 함수를 사용할 때는 부등식, 조건식에서 주의를 기울이며 사용해야겠다.

 

'C' 카테고리의 다른 글

매개변수에 전역변수  (0) 2022.05.13
LinkedList  (0) 2022.05.10
shallow & deep copy  (1) 2022.04.27
main(int argc, char** argv)  (0) 2022.04.26
문자열  (2) 2022.04.21

C에서는 문자열은 문자를 가리키는 포인터이다. 이게 굉장히 중요하면서 헷갈린다.

문자를 가리키는 포인터라면, 주소를 안다면 다음 문자의 주소도 있지 않을까?

 

아래 예제에서 확인해본다.

 

 

문자의 주소(문자열 str 주소) 와 다음 문자 'u', 'n' 의 주소이다.

 

 

맞다. 문자열은 주소이다. 1바이트씩 증가하며 문자를 저장하고 있다.

그럼 당연히 조작도 가능하지 않을까? 라는 생각에 접근하여 문자를 변경해본다.

 

 

두 번째문자 'u' 'o' 변경을 시도했지만 "Segmentation fault" 에러가 나왔다.

잘못된 주소접근? 정도로 해석할 있을 같다. 안될까?

주소로 접근이 가능하고 배열로도 출력이 되는데 수정이 안될까?

 

문자열을 저장하는 메모리영역은 text segment 이다.

배열을 통한 문자열 저장은 stack 이지만, 이 곳은 프로그램의 코드나 변수명이 저장되는 곳이고 read-only 영역이다.

때문에 수정이 불가하고 읽기만 가능한 것이다.

 

포인터변수에 리터럴 초기화는 읽기전용으로만 사용하자.

책에서는 안전하고 명확히 표현하고자 const 곁들여 쓰자고 제안한다.

 

const char* name = "John";

 

'C' 카테고리의 다른 글

매개변수에 전역변수  (0) 2022.05.13
LinkedList  (0) 2022.05.10
shallow & deep copy  (1) 2022.04.27
main(int argc, char** argv)  (0) 2022.04.26
(unsigned int)1 - (unsigned int)2 > 0 ? yes : no  (1) 2022.04.23

+ Recent posts