const 선언 시, 선언된 변수의 주소값도 못바꾸나요?

scs9802의 이미지

const struct a{... next. = &b}
const struct b{... }
const struct c{... next. = &b}

const로 선언된 구조체를 이용하여

a->b chain 에서 a->c->b chain 으로 변경하는 작업을 수행중입니다.

const 로 선언되어있어 next 값을 변경시키는것이 불가능합니다.

혹시 const 로 선언된 구조체의 주소값 또한 변경시킬 수 없나요?

jick의 이미지

const이든 아니든 일단 정의된 변수의 주소값은 프로그램에서 바꿀 수 없습니다.

scs9802의 이미지

그러면 위 문제를 해결할만한 아이디어가 있을까요 .?

나빌레라의 이미지

포인터로 바꾸세요.

----------------------
얇은 사 하이얀 고깔은 고이 접어서 나빌레라

scs9802의 이미지

감이 오지 않아서 그러는데 어떤식으로 바꾸면 될까여?
*a->next = &b 를 하게되면
*a는 읽기전용값이라서 값 변경이 이루어 지지 않습니다.

익명 사용자의 이미지

만약 포인터가 가리키는 객체가 애초에 원래 상수가 아니었다면, 이런 짓을 해 볼 수 있긴 합니다.

#include <stdio.h>
 
static const int *next(const int *);
 
int main(void) {
	int array[] = {1, 2, 3};
 
	const int *const_ptr = next(&array[0]);
	// *const_ptr = -100; error!
	int *ptr = (int *)const_ptr;
	*ptr = -200;
 
	for (int i=0; i<3; ++i){
		printf("%d ", array[i]);
	}
	puts("");
	return 0;
}
 
static const int *next(const int *p){
	return p + 1;
}

상수에 대한 포인터를 일반 포인터로 캐스팅해서 접근한 겁니다.
C언어에서 이런 짓을 해야만 하는 경우가 종종 있어요.

예컨대 strchr 함수 같은 것을 보시면, const char *로 문자열 입력을 받습니다.
strchr 함수 자체는 문자열을 수정할 이유가 전혀 없으니까 적절한 선택이었겠지만, 이 함수를 쓰는 입장에서는 non-const 문자열을 넘겨 호출할 경우 non-const 문자를 가리키는 포인터를 받고 싶지 않겠어요?
C++였다면 함수 오버로딩이 가능하니 상수 버전, 비상수 버전을 따로 만들면 그만이지만, C언어에선 그것도 불가능하죠.
결국 C언어의 strchr는 상수 포인터를 받아서 비상수 포인터를 반환하게 되어 있습니다.

위 코드가 안전하게 동작하는 이유는, 애초에 array의 원소들이 non-const로 정의되었기 때문입니다. 그걸 가리키는 포인터에 const가 붙은 게 문제였을 뿐, 애초에 non-const로 정의된 object를 수정하는 건 문제가 없죠.

만약 귀하께서 위 테크닉(포인터 캐스팅으로 const 없애기)을 이용해서 원래 const였던 object를 수정하려고 시도한다면, undefined behavior가 발생하여 그 결과는 예측할 수 없게 됩니다.

댓글 달기

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
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.