Различие между использованием символьных указателей и символьными массивами

Я использую Zend_Test для завершенного тестирования всех контроллеров. Довольно просто настроить, поскольку только необходимо настроить файл начальной загрузки (сам файл начальной загрузки не должен диспетчеризировать фронтальный контроллер!). Мой основной класс тестового сценария похож на это:

abstract class Controller_TestCase extends Zend_Test_PHPUnit_ControllerTestCase
{
    protected function setUp()
    {
        $this->bootstrap=array($this, 'appBootstrap');
        Zend_Auth::getInstance()->setStorage(new Zend_Auth_Storage_NonPersistent());
        parent::setUp();
    }

    protected function tearDown()
    {
        Zend_Auth::getInstance()->clearIdentity();
    }

    protected function appBootstrap()
    {
        Application::setup();
    }
}

, где Application::setup(); делает всю установку задачи, которые также настраивают реальное приложение. Простой тест тогда был бы похож на это:

class Controller_IndexControllerTest extends Controller_TestCase
{
    public function testShowist()
    {
        $this->dispatch('/');
        $this->assertController('index');
        $this->assertAction('list');
        $this->assertQueryContentContains('ul li a', 'Test String');
    }
}

Это - все...

17
задан Dave 28 September 2011 в 22:13
поделиться

8 ответов

Прочтите эту статью ниже:

Также см. В случае массива символов, как в вашем случае, char new_str [], тогда new_str будет всегда указывают на основание массива. Указатель сам по себе не может быть увеличен. Да, вы можете использовать индексы для доступа к следующему символу в массиве, например: new_str [3] ;

Но в случае указателя на char указатель может быть увеличен new_str ++ для извлечения вы следующий символ в массиве.

Также я бы предложил эту статью для большей ясности.

9
ответ дан 30 November 2019 в 13:05
поделиться

Отличным источником для устранения путаницы является Питер Ван дер Линден, эксперт по программированию на C, Deep Секреты C - то, что массивы и указатели не совпадают, - это то, как они адресуются в памяти.

В массиве

char new_str[];
компилятор присвоил new_str адрес памяти, который известен как во время компиляции, так и во время выполнения, например, 0x1234, следовательно, индексирование new_str выполняется просто с помощью []. Например, new_str[4] во время выполнения код выбирает адрес, в котором находится new_str, например, 0x1234 (это адрес в физической памяти). добавив к нему спецификатор индекса [4], 0x1234 + 0x4, можно получить значение.

Принимая во внимание, что с помощью указателя компилятор дает символу

char *newstr
адрес, например, 0x9876, но во время выполнения этот адрес используется по схеме косвенной адресации. Предположим, что newstr был malloc'd
newstr = malloc(10);
, происходит то, что каждый раз, когда ссылка в коде делается для использования newstr, поскольку адрес newstr известен компилятору, то есть 0x9876, но то, на что указывает newstr, является переменной . Во время выполнения код извлекает данные из физической памяти 0x9876 (т.е. newstr), но по этому адресу находится другой адрес памяти (так как мы его присвоили), например 0x8765, он здесь, код извлекает данные из этого адреса памяти, который malloc назначается newstr, то есть 0x8765.

char new_str [] и char * newstr используются взаимозаменяемо, поскольку индекс нулевого элемента массива превращается в указатель , и это объясняет, почему вы можете newstr [5] или * (newstr + 5) Обратите внимание, как используется выражение указателя, даже если мы объявили char * newstr , следовательно,

*(new_str + 1) = *newstr;
ИЛИ
*(new_str + 1) = newstr[1];

Таким образом, реальная разница между ними заключается в том, как к ним обращаются в памяти.

Возьмите книгу и прочтите ее, проживите ее и вдохните. Блестящая книга! :)

9
ответ дан 30 November 2019 в 13:05
поделиться

Если вы используете C ++, как указывают ваши теги, вам действительно следует использовать строки C ++, а не массивы C char .

Тип string значительно упрощает работу со строками.

Если вы по какой-то причине застряли с массивами char , строка:

char new_str[] = "";

выделяет 1 байт пространства и помещает в него нулевой символ терминатора. Он немного отличается от:

char *new_str = "";

, поскольку может дать вам ссылку на незаписываемую память. Утверждение:

char *new_str;

само по себе дает вам указатель, но ничего, на что он указывает. Он также может иметь случайное значение, если оно локально для функции.

Что люди обычно делают (в C, а не C ++), так это делают что-то вроде:

char *new_str = malloc (100); // (remember that this has to be freed) or
char new_str[100];

, чтобы получить достаточно места.

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

1
ответ дан 30 November 2019 в 13:05
поделиться

Разница в том, что один является указателем, а другой - массивом. Вы можете, например, использовать массив sizeof (). Возможно, вам будет интересно посмотреть здесь

2
ответ дан 30 November 2019 в 13:05
поделиться

Если вы ' re в C ++, почему бы не использовать std :: string для всех ваших строковых потребностей? Особенно все, что связано с конкатенацией. Это избавит вас от множества проблем.

-2
ответ дан 30 November 2019 в 13:05
поделиться

Тип первого - char [1], второго - char *. Различные типы.

Выделите память для последнего с помощью malloc в C или new в C ++.

char foo[] = "Bar";  // Allocates 4 bytes and fills them with
                     // 'B', 'a', 'r', '\0'.

Размер здесь подразумевается из строки инициализатора.

содержимое foo изменяемо. Вы можете изменить foo [i] , например, где i = 0..3.

OTOH, если вы это сделаете:

char *foo = "Bar";

Теперь компилятор выделяет статическую строку «Bar» находится в памяти только для чтения и не может быть изменен.

foo[i] = 'X';  // is now undefined.
1
ответ дан 30 November 2019 в 13:05
поделиться

Это массив символов:

char  buf [1000];

Так, например, это не имеет смысла:

buf = &some_other_buf;

Это потому, что buf , хотя и имеет характеристики указателя типа , он уже указывает на единственное место, которое имеет для него смысл.

char *ptr;

С другой стороны, ptr является только указателем и может указывать куда-то. Чаще всего это что-то вроде этого:

ptr = buf;              // #1:  point to the beginning of buf, same as &buf[0]

или, может быть, так:

ptr = malloc (1000);    // #2:  allocate heap and point to it

или:

ptr = "abcdefghijklmn"; // #3:  string constant

Для всех этих типов * ptr может быть записано, за исключением третьего случая, когда некоторая среда компиляции определяет строковые константы, которые нельзя записывать.

*ptr++ = 'h';          // writes into #1: buf[0], #2: first byte of heap, or
                       //             #3 overwrites "a"
strcpy (ptr, "ello");  // finishes writing hello and adds a NUL
6
ответ дан 30 November 2019 в 13:05
поделиться
char new_str[]="abcd";  

Это определяет массив символов (строку) размером 5 байт (один байт для каждого символа плюс один для нулевого терминатора). Таким образом, в памяти хранится строка 'abcd', и мы можем получить доступ к этой строке, используя переменную new_str.

char *new_str="abcd";  

Это указывает, что строка 'abcd' хранится где-то в памяти, а указатель new_str указывает на первый символ этой строки.

0
ответ дан 30 November 2019 в 13:05
поделиться