Полоса имитатора Python () функционирует в C

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

, Когда Вы видите что-то как:

int a

в C++, компилятор выкладывает код, который резервирует четыре байта памяти и затем присваивает локальный символ "a" для указания на ту память. Если у Вас был язык сценариев без типов как JavaScript, интерпретатор, негласно, выделяет требуемую память. Можно сделать:

var a = 10;  // a is probably a four byte int here
a = "hello world"; // now a is a 12 byte char array

существует много, который происходит между теми двумя строками. Интерпретатор удаляет память в a, выделяет новый буфер для символов, затем присваивает var для указания на ту новую память. На языке со строгим контролем типов нет никакого интерпретатора, который управляет этим для Вас, и таким образом компилятор должен записать инструкции, которые принимают во внимание тип.

int a = 10; // we now have four bytes on the stack.
a = "hello world"; // wtf? we cant push 12 bytes into a four byte variable! Throw an error!

Так компиляторы мешает тому коду компилировать так ЦП dosn't, вслепую пишут 12 байтов в четырехбайтовый буфер и вызывают страдание.

добавленные издержки для компилятора, пишущий дополнительные инструкции заботиться о типе значительно замедлили бы язык и удалили бы преимущество языков как C++.

:)

РЕДАКТИРОВАНИЕ-nelson

в ответ на комментарий

я не знаю много о Python, таким образом, я не могу сказать многое об этом. Но свободно typedness значительно замедляет время выполнения. Каждая инструкция, что интерпретатор (VM) вызовы должен оценить, и при необходимости, принуждает var в ожидаемый тип. Если Вы имеете:

mov a, 10
mov b, "34"
div a, b

Затем интерпретатор должен удостовериться, что переменной и числа, затем должен был бы принудить b в число прежде, чем обработать инструкцию. Добавьте, что наверху для каждой инструкции, что VM выполняется и у Вас есть путаница на Ваших руках :)

5
задан Dave Jarvis 28 September 2009 в 17:42
поделиться

4 ответа

Не существует стандартной реализации C для функции strip () или trim (). Тем не менее, вот тот, который включен в ядро ​​Linux:

char *strstrip(char *s)
{
        size_t size;
        char *end;

        size = strlen(s);

        if (!size)
                return s;

        end = s + size - 1;
        while (end >= s && isspace(*end))
                end--;
        *(end + 1) = '\0';

        while (*s && isspace(*s))
                s++;

        return s;
}
10
ответ дан 18 December 2019 в 07:10
поделиться

I wrote C code to implement this function. I also wrote a few trivial tests to make sure my function does sensible things.

This function writes to a buffer you provide, and should never write past the end of the buffer, so it should not be prone to buffer overflow security issues.

Note: only Test() uses stdio.h, so if you just need the function, you only need to include ctype.h (for isspace()) and string.h (for strlen()).

// strstrip.c -- implement white space stripping for a string in C
//
// This code is released into the public domain.
//
// You may use it for any purpose whatsoever, and you don't need to advertise
// where you got it, but you aren't allowed to sue me for giving you free
// code; all the risk of using this is yours.



#include <ctype.h>
#include <stdio.h>
#include <string.h>



// strstrip() -- strip leading and trailing white space from a string
//
// Copies from sIn to sOut, writing at most lenOut characters.
//
// Returns number of characters in returned string, or -1 on an error.
// If you get -1 back, then nothing was written to sOut at all.

int
strstrip(char *sOut, unsigned int lenOut, char const *sIn)
{
    char const *pStart, *pEnd;
    unsigned int len;
    char *pOut;

    // if there is no room for any output, or a null pointer, return error!
    if (0 == lenOut || !sIn || !sOut)
        return -1;

    pStart = sIn;
    pEnd = sIn + strlen(sIn) - 1;

    // skip any leading whitespace
    while (*pStart && isspace(*pStart))
        ++pStart;

    // skip any trailing whitespace
    while (pEnd >= sIn && isspace(*pEnd))
        --pEnd;

    pOut = sOut;
    len = 0;

    // copy into output buffer
    while (pStart <= pEnd && len < lenOut - 1)
    {
        *pOut++ = *pStart++;
        ++len;
    }


    // ensure output buffer is properly terminated
    *pOut = '\0';
    return len;
}


void
Test(const char *s)
{
    int len;
    char buf[1024];

    len = strstrip(buf, sizeof(buf), s);

    if (!s)
        s = "**null**";  // don't ask printf to print a null string
    if (-1 == len)
        *buf = '\0';  // don't ask printf to print garbage from buf

    printf("Input: \"%s\"  Result: \"%s\" (%d chars)\n", s, buf, len);
}


main()
{
    Test(NULL);
    Test("");
    Test(" ");
    Test("    ");
    Test("x");
    Test("  x");
    Test("  x   ");
    Test("  x y z   ");
    Test("x y z");
}
0
ответ дан 18 December 2019 в 07:10
поделиться

Python strings ' метод полосы удаляет как конечные, так и ведущие пробелы. Две половины проблемы сильно различаются при работе со "строкой" C (массив символов, завершенный \ 0).

Для конечных пробелов: установите указатель (или эквивалентный индекс) на существующий конечный \ 0. Уменьшайте указатель до тех пор, пока он не коснется начала строки или любого небелого символа; установите \ 0 сразу после этой точки завершения-сканирования в обратном направлении.

Для начальных пробелов: установите указатель (или эквивалентный индекс) на начало строки; продолжайте увеличивать указатель, пока он не достигнет небелого символа (возможно, конечного \ 0); memmove остаток строки так, чтобы первый не белый цвет переместился в начало строки (и аналогично для всего последующего).

12
ответ дан 18 December 2019 в 07:10
поделиться

Если вы хотите удалить вместо , последний символ новой строки в строке, вы можете использовать этот фрагмент:

size_t s = strlen(buf);
if (s && (buf[s-1] == '\n')) buf[--s] = 0;

Чтобы точно имитировать строку Python str. strip ([chars]) (так, как я интерпретировал его работу), вам необходимо выделить место для новой строки, заполнить новую строку и вернуть ее. После этого, когда вам больше не нужна очищенная строка, вам нужно освободить используемую память, чтобы не было утечек памяти.

Или вы можете использовать указатели C и изменить начальную строку и добиться аналогичного результата.
Предположим, ваша начальная строка - "____ сорок два ____ \ n" , и вы хотите удалить все подчеркивания и '\ n'

____forty two___\n
^ ptr

. Если вы измените ptr на 'f' и первый '_' после два с '\ 0' результат такой же, как у Python "____ сорок два ____ \ n" .strip ("_ \ n") ;

____forty two\0___\n
    ^ptr

Опять же, это не то же самое, что Python. Строка изменяется на месте, второй строки нет, и вы не можете отменить изменения (исходная строка потеряна).

0
ответ дан 18 December 2019 в 07:10
поделиться
Другие вопросы по тегам:

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