Как этот C кодирует работу?

Я следовал ниже шагов для закрытия filezilla.

В терминале, введите ниже для списка всех рабочих процессов.

ps -A

Это даст Вам список выполнения процессов. Найдите идентификатор процесса, который имеет имя "filezilla", и уничтожьте процесс. В моей системе идентификатор процесса является 1759.

kill 1759

Filezilla закроется немедленно. Спасибо.

11
задан sigjuice 1 September 2009 в 14:58
поделиться

10 ответов

Строка 2 проверяет, является ли текущий символ нулевым ограничителем строки - поскольку строки C заканчиваются нулем, и нулевой символ считается ложным значением, он начнет разворачивать рекурсию, когда достигнет конца строки (вместо попытки вызвать StrReverse4 для символа после нулевого терминатора, который будет за пределами допустимых данных).

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

Пример:

 0  1  2  3
+--+--+--+--+
|f |o |o |\0|
+--+--+--+--+
  1. Когда str = 0 , тогда * str равно 'f' , поэтому рекурсивный вызов выполняется для str + 1 = 1.
  2. Когда str = 1 , тогда * str равно 'o' , поэтому рекурсивный вызов выполняется для str + 1 = 2.
  3. Когда str = 2 , тогда * str равно 'o' , поэтому рекурсивный вызов выполняется для str + 1 = 3.
  4. Когда str = 3 , тогда * str равно '\ 0' и \ 0 является ложным значением, поэтому if (* str) оценивается как false, поэтому рекурсивный вызов не выполняется, таким образом, возвращаясь к рекурсии, которую мы получаем ...
  5. За последней рекурсией следовала `putchar ('o'), затем после этого,
  6. За следующей самой последней рекурсией следует` putchar ('o'), затем после этого,
  7. За самой последней рекурсией следует `putchar ('f') ,и мы закончили.
38
ответ дан 3 December 2019 в 01:09
поделиться

Тип строки C - не что иное, как указатель на char. По соглашению указатель указывает на массив символов, оканчивающийся нулевым байтом .

* str , таким образом, является первым символом строки, на которую указывает ] str .

Использование * str в условном выражении оценивается как false , если str указывает на завершающий нулевой байт в (пустой) строке .

3
ответ дан 3 December 2019 в 01:09
поделиться

Строка 2 проверяет, является ли текущий символ нулевым ограничителем строки - поскольку строки C являются нулевыми. завершен, а нулевой символ считается ложным значением, он начнет развертывание рекурсии, когда достигнет конца строки (вместо попытки вызвать StrReverse4 для символа после нулевого терминатора,

2
ответ дан 3 December 2019 в 01:09
поделиться

В конце строки стоит 0 - значит, у вас есть "test" => [0] 't' [1] 'e' [2] 's' [3] 't' [4] 0

и if (0) -> false

, таким образом это будет работать.

1
ответ дан 3 December 2019 в 01:09
поделиться

В строке 3 указатель всегда будет увеличиваться до следующего блока (4 байта, так как это целое число) ...

Это неверно, это char *, это будет только увеличивается на 1. Поскольку длина char составляет всего 1 байт.

Но как это использовать в качестве аргумента условного оператора (который должен исключать логическое право?)?

Вы можете использовать любое значение в if ($$) в $$, и он будет только проверять, отличен ли он от нуля, в основном bool также реализован как простые 1 = true и 0 = false.

В другой строго типизированный язык более высокого уровня, в if вы не можете использовать такие вещи, но в C все сводится к числам. И вы можете использовать что угодно.

if(1) // evaluates to true 
if("string")  // evaluates to true
if(0) // evaulates to false

Вы можете передать что угодно в if, а условия в C.

1
ответ дан 3 December 2019 в 01:09
поделиться

условные операторы ( if , для , while и т. Д.) Ожидают логического выражения. Если вы указываете целочисленное значение, оценка сводится к 0 == false или не-0 == true . Как уже упоминалось, завершающий символ c-строки - это нулевой байт (целочисленное значение 0). Таким образом, if завершится ошибкой в ​​конце строки (или первом нулевом байте в строке).

В стороне, если вы сделаете * str для NULL-указателя, вы вызывают неопределенное поведение; вы всегда должны проверять действительность указателя перед разыменованием.

0
ответ дан 3 December 2019 в 01:09
поделиться

C не имеет концепции логических значений: в C каждый скалярный тип (то есть арифметические типы и типы указателей) можно использовать в логических контекстах, где 0 означает ложь и ненулевое значение истина .

Поскольку строки заканчиваются нулем, терминатор будет интерпретироваться как ложь , тогда как все остальные символы (с ненулевым значением!) будет истинным . Это означает, что существует простой способ перебора символов строки:

for(;*str; ++str) { /* so something with *str */ }

StrReverse4 () делает то же самое, но путем рекурсии вместо итерации.

0
ответ дан 3 December 2019 в 01:09
поделиться

1.

str - указатель на char. Увеличение str заставит указатель указывать на второй символ строки (так как это массив символов). ПРИМЕЧАНИЕ: Увеличивающие указатели будут увеличиваться в зависимости от типа данных, на который указывает указатель.

Например:

int *p_int;
p_int++;     /* Increments by 4 */

double *p_dbl;
p_dbl++;      /* Increments by 8 */

2.

if(expression)
{
   statements;
}

Выражение вычисляется, и если результирующее значение равно нулю ( NULL , \ 0 , 0 ), операторы не выполняются. Поскольку каждая строка заканчивается на \ 0 , рекурсия должна закончиться через некоторое время.

0
ответ дан 3 December 2019 в 01:09
поделиться

Попробуйте этот код, такой же простой, как тот, который вы используете:

int rev(int lower,int upper,char*string)
{
  if(lower>upper)
          return 0;
   else
          return rev(lower-1,upper-1,string);
}
0
ответ дан 3 December 2019 в 01:09
поделиться

Это вроде как не по теме, но когда я увидел вопрос, я сразу подумал, действительно ли это быстрее, чем просто выполнение strlen и итерации сзади.

Итак, я сделал небольшой тест.

#include <string.h>

void reverse1(const char* str)
{
    int total = 0;
    if (*str) {
            reverse1(str+1);
            total += *str;
    }
}

void reverse2(const char* str)
{
    int total = 0;
    size_t t = strlen(str);
    while (t > 0) {
            total += str[--t];
    }
}

int main()
{
    const char* str = "here I put a very long string ...";

    int i=99999;

    while (--i > 0) reverseX(str);
}

Сначала я скомпилировал его с X = 1 (используя функцию reverse1), а затем с X = 2. Оба раза с -O0.

Он последовательно возвращал примерно 6 секунд для рекурсивной версии и 1,8 секунды для версии strlen.

Я думаю, это потому, что strlen реализован на ассемблере, а рекурсия добавляет довольно накладные расходы.

Я совершенно уверен, что тест репрезентативен, если я ошибаюсь, поправьте меня.

В любом случае, я подумал, что должен поделиться этим с вами.

0
ответ дан 3 December 2019 в 01:09
поделиться
Другие вопросы по тегам:

Похожие вопросы: