2015-01-03 2 views
1

В приведенном ниже примере strchr приведен пример данного примера.Вычитание массива char из указателя char создает int?

/* strchr example */ 
#include <stdio.h> 
#include <string.h> 

int main() 
{ 
    char str[] = "This is a sample string"; 
    char * pch; 
    printf ("Looking for the 's' character in \"%s\"...\n",str); 
    pch=strchr(str,'s'); 
    while (pch!=NULL) 
    { 
    printf ("found at %d\n",pch-str+1); 
    pch=strchr(pch+1,'s'); 
    } 
    return 0; 
} 

Почему вычитание char массива str из char указателя pch плюс один дать int? (как обозначается форматом %d) Если я удалю «-str», программа не будет выполняться до тех пор, пока я не изменю %d на %s.

+2

Массивы распада на указатели при использовании в выражении и разности указателей - это расстояние (количество элементов) между ними. – zch

+0

@zch: Хорошо, что вы очистили путаницу OPs от семантики массива. Но как же его вопрос? – Deduplicator

ответ

3

Короткий его в том, что это ошибка :
Это выражение может быть типа int, или вы можете иметь Неопределенное поведение в вызове printf.

Давайте шаг за шагом:

  1. Вы на самом деле не вычитая массив из указателя, а указатель с указателем:
    почти во всех контекстах, в array decays to a pointer to its first element.

  2. Какая разница между двумя указателями (что определено только в том случае, если они указывают на или непосредственно за элементами из того же массива)?

    ptrdiff_t (Это то, что typedef в <stddef.h> для.)

  3. ptrdiff_t может случиться быть int, но не зависят от него.
    Вместо этого используйте соответствующий формат-спецификатор: %ti.

+1

Может быть, это было лучшее решение ответить на него (+1) –

+0

Просто любопытно: Что это за «массив * имя * распадается»? (а не просто «массив распадается»), я видел это здесь довольно часто. – mafso

+0

@mafso Отредактировано в соответствующей ссылке для более подробного объяснения. –

0

Имена массивов распадается на указатели (в большинстве случаев) на первый элемент. Вычитание двух указателей дает данные типа ptrdiff_t, при условии, что обе точки относятся к элементам того же массива.

-2

Вы смотрите на одну из странностей C/C++ и указатели. Синтаксис и семантика указателя и массива - просто орехи.

str является указателем на символ (а также массив). pch - указатель на символ.

Если вы вычтите два указателя на один и тот же тип, вы получите количество элементов между ними.

Вы можете даже сделать

3 [str] ; 

что эквивалентно

str[3] ; 

и эквивалентно

*(str+3) ; 

Ваше выражение:

pch - 1 

имеет указатель на символ. Ваше выражение

pch - str 

имеет тип int.

+0

Ничто из вашего сообщения никак не затрагивает вопрос OPs, который касался ** типа ** разницы. Кроме того, указатели и массивы принципиально отличаются друг от друга, и объединение их является распространенным источником ошибок и разочарований, хотя (или, возможно, больше потому, что) существует распад массива. – Deduplicator

 Смежные вопросы

  • Нет связанных вопросов^_^