2013-09-03 5 views
1

Я хотел бы понять, почему некоторые символы исчезают и после них находятся , объединенных в исходную строку. См., c = *sibl принимает первый символ , *sibl = *inout получает содержимое *inout, но символ, хранящийся в c, не больше в *inout. И, *inout = c не меняет содержание *inout, он составляет c, будет конкатенироваться с содержанием *inout. Я не понимаю, почему это происходит!Проблемы с пониманием операций с указателями на языке C

Мой код:

void Cripto (char *inout, int i) { 
    char *sibl, c; 
    while (*inout) { 
     sibl = inout+1; 
     if (!sibl) 
      break; 
     if (*inout >= 'A' && *inout <= 'Z'){ 
      *inout += i; 
     } 
     c = *sibl; 
     printf("val c %c\n",c); 
     printf("val inout after c %s\n",inout); 
     printf("val sibl after c %s\n",sibl); 
     *sibl = *inout; 
     printf("val sibl after att %s\n",sibl); 
     *inout = c; 
     printf("val inout after att %s\n",inout); 
    inout = sibl+1; 
    } 
} 

int main() { 
    char str[30]; 
    int i; 
    scanf("%s %d", str, &i); 
    Cripto(str, i); 
    printf("%s\n", str); 
    return 0; 

}

результаты для "Тест" 3:

val c: e 
val inout after c: teste 
val sibl after c: este 
val sibl after att: tste 
val inout after att: etste 
val c: t 
val inout after c: ste 
val sibl after c: te 
val sibl after att: se 
val inout after att: tse 
val c: 
val inout after c: e 
val sibl after c:  
val sibl after att: e 
val inout after att: 
+1

Можете ли вы сузить это до определенной вещи, которую вы не понимаете? Эта программа многое делает, и неясно, с чем вы столкнулись. – interjay

ответ

2

еще одна вещь, которую вы должны быть осторожными (если вы не делаете это intentionlly) являются следующие две строки:

sibl = inout+1; 
*sibl = *inout; 

вы указывающими SIBL к Inout + 1, а затем, присваивающих значение SIBL (который, по существу, указатель на inout + 1) значением inout. Это изменит значение самого inout. Таким образом, если inout является («123»), то сибл указывает на «23» и с «* sibl = * inout», вы устанавливаете символ seccond inout (который является sibl) с первым символом. Таким образом, inout станет «113».

1

Причина вашей проблемы в том, что вы переборе в while() петле этапы 2:

while(*inout) { 
    sibl = inout+1; 
    // ... 
    inout = sibl+1; // = (inout+1)+1 = inout+2 
} 

Что вы , кажется, пытается сделать итерацию по строке, адресуемой inout и добавить i (предположительно небольшое значение), если char является заглавная буква, так почему бы не использовать что-то вроде:

while(*inout) { 
    if(*inout>='A' && *inout<='Z') { 
     *inout += (char)i; 
    } 
    inout++; 
} 
1

В этом коде отсутствует конкатенация. Происходит только переписывание. Вот, что делает код:

  1. У вас есть строка в некотором буфере памяти, который служит для ввода и вывода. Переменная inout - это указатель, начинающийся в начале этой строки. Однако по мере продвижения этой функции этот указатель модифицируется так, чтобы указывать на другие символы внутри этой строки. Таким образом, когда вы позже выведете строку, на которую указывает, будет напечатан только суффикс строки. Префикс все еще существует, но строка C всегда интерпретируется от указателя начала до конечного нулевого символа.

  2. В первой итерации inout является указателем на первый символ, sibl делается для указания на второй символ во входном массиве. Если любой из них указывает на завершающий нулевой символ, цикл завершается.

  3. Если символ, который inout указывает на верхний регистр, его значение ASCII увеличивается на i. В качестве побочного элемента: эта операция не обратима, поскольку она записана, потому что 'Z' + 3 (или аналогичный) будет отображать некоторый не-буквенно-цифровой символ, который сам по себе не будет изменен.

  4. Последовательность c = *inout; *inout = *sibl; *sibl = c заменяет два соседних символа.

  5. inout = sibl + 1; эффективно перемещает inout вперед два символов, так как sibl был последний набор для inout + 1

  6. второй итерации делает то же самое для персонажей 3 и 4, как первая итерация сделала персонаж 1 и два. Вы больше не видите результат первой итерации в своем printf, потому что эти два символа теперь находятся перед двумя указателями и в основном недоступны внутри функции. Тем не менее, указатель в main не изменяется, и последний printf должен дать вам весь результат операции.

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