strlen в функции, изменяющей вывод - PullRequest
0 голосов
/ 04 марта 2020

Хорошо, я попытался понять это, но не смог;

Так что в моем исходном коде есть функция с двумя передаваемыми аргументами (9 и 1, как строки)

char * plus( char *a, char *b ){
   char sa[101] = {0};
   char sb[101] = {0};
   static char _s[101] = {0};
   int i;
   int st = 0;
   int sto;
   for( i = strlen( a ) - 1; i >= 0; i-- ){
       sa[strlen( a ) - 1 - i] = a[i]; 
   }
   for( i = strlen( b ) - 1; i >= 0; i-- ){
       sb[strlen( b ) - 1 - i] = b[i];
   }
   for( i = 0; i < strlen( sa ); i++ ){
       sto = 0;
       if(( sa[i] + sb[i] + st - 2 * '0' ) > 9 ) sto = 1;
       sa[i] = ( sa[i] + sb[i] + st - 2 * '0' ) %10 + '0';
       st = sto;
       if( st && sa[i + 1] == 0) sa[i + 1] = '1';
   }
   for( i = strlen( sa ) - 1; i >= 0; i-- ){
       _s[strlen( sa ) - 1 - i] = sa[i];
   }
   return _s;
}

Должно возвращаться «10», но вместо «* 0», но постоянно (поэтому не «неопределенное поведение»). Что не так?

Редактировать:

если я передам strlen( a ) вместо strlen( sa ) в строке for( i = 0; i < strlen( sa ); i++ ){ тогда он работает правильно

Ответы [ 2 ]

3 голосов
/ 04 марта 2020

sa [i] + sb [i] + st - 2 * '0'

отрицательно. Поскольку вы делаете sa[i + 1] = '1', то strlen(sa) get увеличивается на l oop. Из-за этого sb[i] равно 0, потому что это символ завершения нуля при последнем запуске, когда i == strlen(sa) == 2. Тогда вычисление становится следующим:

sa[i] + sb[i] + st - 2 * '0' = 
  '1' +     0 +  1 - 2 * '0' = 
   49 +     0 +  1 - 2 * 48  =
                50 - 96      =
                -46 

Поскольку это минус 46, sa [i] becomaes:

a[i] = ( sa[i] + sb[i] + st - 2 * '0' ) %10 + '0' =
                                    -46 %10 + '0' =
                                         -6 + '0' =
                                              '*'

Скорее всего, в l oop:

 for( i = 0; i < strlen( sa ); i++ ){

Вы должны позаботиться о том, что происходит, когда длины строк не равны. Вы делаете sa[i] = '1', но sb остается прежним. Думаю, сейчас вы можете это исправить, заменив

  sa[i] + sb[i] + st - 2 * '0'

чем-то вроде:

  sa[i] - '0' + (sb[i] ? sb[i] - '0' : '0') + st

Примечания: мне не нравятся ваши отступы. Пожалуйста, сделайте ваш код максимально читабельным. Используйте новые строки для обозначения новых выражений. Используйте { } для обозначения места ввода l oop или тел.

1 голос
/ 04 марта 2020

Это l oop

   for( i = 0; i < strlen( sa ); i++ ){
       sto = 0;
       if(( sa[i] + sb[i] + st - 2 * '0' ) > 9 ) sto = 1;
       sa[i] = ( sa[i] + sb[i] + st - 2 * '0' ) %10 + '0';
       st = sto;
       if( st && sa[i + 1] == 0) sa[i + 1] = '1';
   }

неверно, потому что внутри l oop изменяется массив sa. Таким образом, также изменяется значение, возвращаемое strlen( sa ), которое вычисляется на каждой итерации.

Когда вы используете strlen( a ) вместо strlen( sa ), тогда массив s не изменяется в l oop , Таким образом, значение, возвращаемое выражением, является фиксированным.

...