Если мне не совсем понятен вопрос, ознакомьтесь с кодом ниже. Почему тест с символом работает, а не с целым числом? В чем заключается это фундаментальное различие между строковым литералом и массивом, которое мне трудно понять?
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;
}
int[]
это не int*
, так что вы не можете передать int[]
где int*&
ссылка ожидается. Тем не менее, int[]
действительно ухудшается в int*
указатель, так что вы можете передать int[]
где int*
ожидается. &
ссылка имеет большое значение. Когда вы передаете что-то по ссылке, это что-то должно соответствовать типу данных, на который ссылается ссылка.
Я предполагаю, что вы имеете в виду: «Почему я могу передать строковый литерал по ссылке, но не массив».
Ну, этот вопрос некорректен, потому что вы можете передать массив по ссылке. Вы также можете передать строковый литерал по ссылке, но ваш код этого не делает. Ваш код передает указатели по ссылке.
void test (char* &a, char* &b)
Эта функция принимает два указателя на символ (char*
) по ссылке.
test (s,t);
s
а также t
оба char*
(не строковые литералы), так что это правильный вызов. Другая функция тестирования:
void test (int* &a, int* &b)
Это также берет указатели (на int) по ссылке. Но вы пытаетесь передать массивы, которые не являются указателями. Для справки, передача строковых литералов (которые являются массивами константных символов) в функцию будет выглядеть следующим образом:
test("help","me")
И это не будет компилироваться с имеющимися у вас перегрузками.
В первом случае вы
так что нет проблем.
В случае, если вы
Часто говорят, что имена массивов имеют разложившиеся функции когда прошло либо непосредственно или же с явным указателем. Ваша функция ожидает, что массив уже распался в указатель перед передачей в функцию.
В синтезе вы должны заранее согласовать тип подписи при запросе ссылки.
В первом случае вы используете указатели
char *s = "help";
char *t = "me";
Таким образом, вы можете изменить их значение, потому что они не являются постоянными.
Учтите, что строковые литералы имеют типы постоянных массивов. Если вы, например, попробуйте позвонить
test ("help", "me" );
вы получите ошибку компиляции, как во втором случае, рассмотренном ниже.
Во втором случае вы пытаетесь преобразовать ссылки на массивы в ссылки на указатели. Нет такого неявного и / или явного преобразования. Таким образом, компилятор выдает ошибку.
Вы могли бы достичь того же эффекта, что и в первом случае, если бы вы написали
int *p = a;
int *q = b;
swap( p, q );