Почему я могу вызывать строковый литерал по ссылке, а не по массиву?

Если мне не совсем понятен вопрос, ознакомьтесь с кодом ниже. Почему тест с символом работает, а не с целым числом? В чем заключается это фундаментальное различие между строковым литералом и массивом, которое мне трудно понять?

using namespace std;

void fun(int &x)
{
cout << x << " okk" << endl;
}

void test (int* &a, int* &b) {
int* temp = a;
a = b;
b = temp;
//cout << *a << " " << &a << endl;
}

void test (char* &a, char* &b) {

cout << &a << " " << &b << endl;
char * temp = a;
a = b;
b = temp;
//cout << *a << " " << &a << endl;
}

int main()
{
char *s = "help";
char *t = "me";

char *u = "help";

cout << s << " " << t << " " << u << endl;

/*char *temp = s;
s = t;
t = temp;
*/

test (s,t);

cout << s << " " << t << endl;

int a[10] = {1,2,3,4,5,6,7,8,9,10};
int b[10] = {11,12,13,14,15,16,17,18,19,20};

cout << *a << " " << *b << endl;

test (a,b);

cout << *a << " " << *b;

}

0

Решение

int[] это не int*, так что вы не можете передать int[] где int*& ссылка ожидается. Тем не менее, int[] действительно ухудшается в int* указатель, так что вы можете передать int[] где int* ожидается. & ссылка имеет большое значение. Когда вы передаете что-то по ссылке, это что-то должно соответствовать типу данных, на который ссылается ссылка.

2

Другие решения

Я предполагаю, что вы имеете в виду: «Почему я могу передать строковый литерал по ссылке, но не массив».

Ну, этот вопрос некорректен, потому что вы можете передать массив по ссылке. Вы также можете передать строковый литерал по ссылке, но ваш код этого не делает. Ваш код передает указатели по ссылке.

void test (char* &a, char* &b)

Эта функция принимает два указателя на символ (char*) по ссылке.

test (s,t);

s а также t оба char* (не строковые литералы), так что это правильный вызов. Другая функция тестирования:

void test (int* &a, int* &b)

Это также берет указатели (на int) по ссылке. Но вы пытаетесь передать массивы, которые не являются указателями. Для справки, передача строковых литералов (которые являются массивами константных символов) в функцию будет выглядеть следующим образом:

test("help","me")

И это не будет компилироваться с имеющимися у вас перегрузками.

0

В первом случае вы

  1. Создание строкового литерала в постоянной памяти
  2. Создание указателя (НЕ массива), который указывает туда
  3. Запрашиваемая ссылка на указатель для обоих аргументов

так что нет проблем.

В случае, если вы

  1. Создание массива целых чисел
  2. Передача массива в функцию, которая ожидает ссылку на указатель на int.

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

В синтезе вы должны заранее согласовать тип подписи при запросе ссылки.

0

В первом случае вы используете указатели

char *s = "help";
char *t = "me";

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

Учтите, что строковые литералы имеют типы постоянных массивов. Если вы, например, попробуйте позвонить

test ("help", "me" );

вы получите ошибку компиляции, как во втором случае, рассмотренном ниже.

Во втором случае вы пытаетесь преобразовать ссылки на массивы в ссылки на указатели. Нет такого неявного и / или явного преобразования. Таким образом, компилятор выдает ошибку.

Вы могли бы достичь того же эффекта, что и в первом случае, если бы вы написали

int *p = a;
int *q = b;

swap( p, q );
0
По вопросам рекламы [email protected]