Const с указателями в C

Я перехожу на C и задаю вопрос об использовании const с указателями. Я понимаю следующий код:

const char *someArray

Это определение указателя, указывающего на типы char, а модификатор const означает, что значения, хранящиеся в someArray, не могут быть изменены. Однако, что означает следующее?

char * const array

Является ли это альтернативным способом указания параметра, который является указателем char для массива с именем "array", который является const и не может быть изменен?

Наконец, что означает эта комбинация:

const char * const s2

Для справки они взяты из книги программирования Deitel C в главе 7, и все они используются в качестве параметров, передаваемых функциям.

Ответы

Ответ 1

const char* является, как вы сказали, указателем на char, где вы не можете изменить значение char (по крайней мере, не через указатель (без исключения константы)).

char* const является указателем на char, где вы можете изменить char, но вы не можете сделать указатель на другой char.

const char* const является постоянным указателем на константу char, то есть вы не можете изменять ни то место, куда указатель указывает, ни значение указателя.

Ответ 3

//pointer to a const
void f1()
{
    int i = 100;
    const int* pi = &i;
    //*pi = 200; <- won't compile
    pi++;
}

//const pointer
void f2()
{
    int i = 100;
    int* const pi = &i;
    *pi = 200;
    //pi++; <- won't compile
}

//const pointer to a const
void f3()
{
    int i = 100;
    const int* const pi = &i;
    //*pi = 200; <- won't compile
    //pi++; <- won't compile

}

Ответ 4

Вам следует попробовать cdecl:

~ $ cdecl
Type `help' or `?' for help
cdecl> explain const char *someArray
declare someArray as pointer to const char
cdecl> explain char * const someArray
declare someArray as const pointer to char
cdecl> explain const char * const s2
declare s2 as const pointer to const char
cdecl>

Ответ 5

char * const array;

Это означает, что указатель является постоянным. Кроме того,

const * const char array;

означает постоянный указатель на постоянную память.

Ответ 6

Повторяя то, что другие пользователи написали, но я хочу предоставить контекст.

Возьмем эти два определения:

void f1(char *ptr) {
    /* f1 can change the contents of the array named ptr;
     * and it can change what ptr points to */
}
void f2(char * const ptr) {
    /* f2 can change the contents of the array named ptr;
     * but it cannot change what ptr points to */
}

Создание самого указателя const, как и в примере f2, является абсолютно почти бессмысленным. Каждый параметр, переданный функции, передается по значению. Если функция меняет это значение, она меняет только локальную копию и не влияет на вызывающий код.

/* ... calling code ... */
f1(buf);
f2(buf);

В любом случае buf не изменяется после вызова функции.


Рассмотрим функцию strcpy()

char *strcpy(char *dest, const char *src);

Одна возможная реализация -

char *strcpy(char *dest, const char *src) {
    char *bk = dest;
    while (*src != '\0') {
        *dest++ = *src++;
    }
    *dest = *src;
    return bk;
}

Эта реализация изменяет как dest, так и src только внутри функции. Создание любого из указателей (или обоих) const ничего не принесло бы для функции strcpy() или вызывающего кода.