Чем отличается массив String от общего массива в C? - PullRequest
0 голосов
/ 23 февраля 2019
#include<stdio.h>
int main()
{
    char str[7];
    scanf("%s",&str);

    for(i=0; i<7; i++)
    {
        printf("%x(%d) : %c\n",&str[i], &str[i], str[i]);
    }

    printf("\n\n%x(%d) : %c      or    %s",&str, &str, str, str);

    return 0;
}

Я не понимаю указатель массива C из-за массива со строкой.

На самом деле я хочу сохранить каждый символ для однострочного ввода.

Это работает, но янашел что-то странное ...

Основная проблема & str и & str [0] имеют одинаковое значение адреса.

Но str имеет строковое значение с% s ..

str [0] имеет символьное значение с% c ..

я использовал str с% c тогда у него есть первые две цифры адреса str .

Что происходит в массиве ..?

Где находится реальный адрес для значения Stirng??

И как scanf ("% s", & str) может распределить строку по каждому пространству массива символов?

Input : 123456789
62fe40(6487616) : 1
62fe41(6487617) : 2
62fe42(6487618) : 3
62fe43(6487619) : 4
62fe44(6487620) : 5
62fe45(6487621) : 6
62fe46(6487622) : 7

62fe40(6487616) : @    123456789

Это окно результатов моего кода.

Ответы [ 3 ]

0 голосов
/ 23 февраля 2019

String - это всего лишь сокращение от zero terminated char array.Таким образом, нет никакой разницы между string и "нормальным" массивом.

Где реальный адрес для значения Стирнга ??

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

Основная проблема заключается в том, что & str и & str [0] имеют одно и то же значение адреса.

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

0 голосов
/ 23 февраля 2019

Чем отличается массив String от общего массива в C?

массив - это непрерывная последовательность объектов одного типа. 1

A string - это непрерывная последовательность символов, оканчивающаяся первым нулевым символом. 2 Таким образом, строка - это просто массив символов, в котором мы отмечаем конецпоставив символ со значением ноль.(Часто строки временно хранятся в больших массивах, которые содержат больше элементов после нулевого символа.)

Таким образом, каждая строка является массивом.Строка - это просто массив с двумя дополнительными свойствами: ее элементы являются символами, а ноль обозначает конец.

& str и & str [0] имеют одинаковое значение адреса.

&str - адрес массива.&str[0] - это адрес первого элемента.

Это одно и то же место в памяти, потому что первый элемент начинается в том же месте, что и массив.Поэтому, когда вы их печатаете или просматриваете, они часто выглядят одинаково.(Адреса могут иметь разные представления, так же, как вы можете написать «200», «двести» или «2 • 10 2 » для одного и того же номера. Так что один и тот же адрес может иногда выглядеть по-разному. В большинствеВ современных системах адрес - это просто число для места в памяти, и вы не увидите различий. Но это может произойти.)

printf("%x(%d) : %c\n",&str[i], &str[i], str[i]);

Это неправильный способ печати адресов.Чтобы правильно распечатать адрес, преобразуйте его в void * и используйте %p 3 :

printf("%p(%p) : %c\n", (void *) &str[i], (void *) &str[i], str[i]);

printf("\n\n%x(%d) : %c or %s",&str, &str, str, str);

Я использовал str с% c, тогда у него есть первые два числа str .

В приведенном выше printf,третья спецификация преобразования - %c, а соответствующий аргумент - str.%c предназначен для использования для символа, 4 , но вы передаете ему аргумент, который является указателем.Возможно, здесь произошло то, что printf использовал указатель, который вы передали ему, как если бы это был int.Тогда printf, возможно, использовал часть этого int, как если бы это был символ, и напечатал его.Итак, вы увидели часть адреса, показанную в виде символа.Тем не менее, немного неясно, когда вы пишете «первые два числа имеют адрес str ».Вы можете показать точный вывод, чтобы уточнить это.

Хотя printf мог использовать указатель, как если бы он был int, поведение для этого не определено стандартом C.Передача неправильного типа для printf преобразования является неправильной, и могут возникнуть другие результаты, в том числе программа, выводящая мусор или сбой.

И как scanf ("% s", & str) распределить строку по каждому пространству массива символов?

Правильный способ передачи str в scanf для %s - передать адрес первого символа, &str[0],C имеет специальное правило для массивов, таких как str: если массив используется в выражении, отличном от операнда sizeof или оператора адреса &, он преобразуется в указатель на свой первый элемент. 5 Таким образом, вы можете использовать scanf("%s", str), и он будет таким же, как scanf("%s", &str[0]).

Однако, когда вы используете scanf("%s",&str), вы передаете адрес массивавместо адреса первого символа.Хотя это одно и то же место, они бывают разных типов.Напомним, что два разных типа указателей на один и тот же адрес могут иметь разные представления.Поскольку scanf не знает фактического типа передаваемого вами аргумента, он должен полагаться на спецификатор преобразования.%s указывает scanf ожидать указатель на символ. 6 Неправильно передавать указатель на массив.

C имеет этот кодПотому что некоторые машины имеют разные типы указателей, а некоторые системы могут передавать разные типы указателей по-разному.Тем не менее, часто код, который передает &str вместо str, ведет себя так, как хотел автор, потому что реализация C использует одно и то же представление для обоих указателей.Таким образом, scanf может фактически получить значение указателя, необходимое для работы %s. 7

Сноски

1 C 2018 6.2.5 20. (Это означает, что информация взята из версии C стандарта 2018 года, ISO / IEC 9899, ​​ Информационные технологии - Языки программирования - C , пункт 6.2.5, пункт 20.)

2 C 2018 7.1.1 1. Обратите внимание, что завершающий нулевой символ считается частью строки, хотя он не учитывается функцией strlen.

3 C 2018 7.21.6.1 8.

4 Технически аргумент должен иметь тип int, а printf преобразует его в unsigned char ипечатает символ с этим кодом.C 2018 7.21.6.1 8.

5 C 2018 6.3.2.1 3. Строковый литерал, используемый для инициализации массива, как в char x[] = "Hello";, также не преобразуется в указатель.

6 C 2018 7.21.6.2 12.

7 Даже если реализация C использует одни и те же представления для разных типов указателей, этоне гарантируйте, что использование одного типа указателя там, где требуется другой, будет работать.Когда компилятор оптимизирует программу, он полагается на то, что автор программы выполнил правила, и оптимизации могут изменить программу таким образом, чтобы это не нарушало программу, которая следовала правилам, но нарушало программу, нарушающую правила.

0 голосов
/ 23 февраля 2019

Вы запутались, потому что строка и массив - это одно и то же.- В памяти есть только данные (и указатели на эти данные)

Когда вы выделяете целое число или буфер для строки, вы резервируете часть этой памяти.Строки в c определяются как последовательность байтов, оканчивающаяся одним байтом со значением 0 - длина неизвестна.С массивом фиксированной длины вы можете работать с известным размером.

Реальное значение строки - указатель на первый символ.

Когда вы печатаете с% c, он ожидает символ- str [0] не указатель - когда вы печатаете с% s, он ожидает указатель на последовательность символов.

printf("\n\n%x(%d) : %c      or    %s",&str, &str, str[0], str);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...