Предупреждение компилятора C ++ (?) При передаче неинициализированной локальной переменной в функцию - PullRequest
0 голосов
/ 01 февраля 2012

Я очень новичок в C ++, поэтому я надеюсь, что кто-то пролил немного света. Я сталкивался с несколькими похожими темами, но мне просто нужно уточнить.

Таким образом, кажется допустимым передавать локальную строку, которая была объявлена, но не инициализирована в функцию. Но почему компилятор жалуется, когда вы пробуете его с помощью int или float ??

Будь то строка, число с плавающей запятой или int, на адрес памяти ссылаются, когда он объявлен, даже если это может быть "мусор"

#include <iostream>
using namespace std;

void load(int);

int main()
{
    int salary;
    load(salary);
    return 0;
}

void load(int sal)
{
    cout << "your salary: " << endl;
    cin >> sal;
    cout << sal << endl;
}

Если я объявлю int или float как глобальную переменную, она будет работать, как и ожидалось, без каких-либо предупреждений. Так лучше ли объявлять переменные в глобальном пространстве (надеюсь, нет)?

Итак, если поместить это в глобальное значение, оно работает:

#include <iostream>
using namespace std;

int salary;
void load(int);

int main()
{
    load(salary);
    return 0;
}

void load(int sal)
{
    cout << "your salary: " << endl;
    cin >> sal;
    cout << sal << endl;
}

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

int foo; 
int returnit(int j)
{ 
    cout << "your salary";
    cin >> j;
    return j; 
} 
int main() 
{ 
    int k = returnit(foo);
    cout << k; 
    return 0;
} 

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

Ответы [ 4 ]

6 голосов
/ 01 февраля 2012

Таким образом, кажется допустимым передавать локальную строку, которая была объявлена, но не инициализирована в функцию. Но почему компилятор жалуется, когда вы пытаетесь с помощью int или float ??

Если под "строкой" вы подразумеваете объект std::string, то это потому, что объекты никогда не инициализируются. Когда вы делаете:

std::string s;

, тогда вызывается конструктор по умолчанию std::string, и объект инициализируется.

Переменные примитивных типов данных (таких как int и float), если только не объявлено, что они имеют статическое время хранения, будут иметь мусор, если не будут явно инициализированы. Попытки прочитать и использовать этот мусор справедливо вызывают предупреждения. (Переменные примитивных типов данных, которые имеют статическую продолжительность хранения (то есть глобальные переменные или переменные, объявленные как static), неявно инициализируются равными 0.)

Так лучше ли объявлять переменные в глобальном пространстве (надеюсь, нет)?

Нет, лучше бы инициализировать переменные.

2 голосов
/ 10 октября 2012

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

Чтобы увидеть, является ли ваша программа логически корректной, используйте метод box и проследите ее. В глобальном блоке есть глобальные переменные, в int main есть свой блок, в котором хранятся локальные переменные, а при вызове функций создайте новый блок для этой функции и заполните его параметрами и локальными переменными. Идите построчно и меняйте значения переменных по мере их изменения в программе. Не забудьте использовать только константы в качестве глобальных переменных. При написании функции будьте осторожны, когда вы передаете по ссылке, что вы понимаете, что функция имеет адрес, который переменные адресуют в памяти и может изменить это значение. При использовании передачи по значению используйте этот вид синтаксиса в объявлении функций:

int Multiplication(const int Var1, const int Var2);

Это защищает значения, которые вы передаете умножению. Синтаксис c ++ создан для скорости и не мешает вам быть логически неправильным.

1 голос
/ 01 февраля 2012
int salary;
load(salary);

Какое значение, по вашему мнению, вы передаете load здесь? Вы передаете бессмысленное значение.

Для ясности, вы не передаете "неинициализированную переменную", вы передаете значение неинициализированной переменной. Если вы делаете:

int j=3;
load(j);

Вы передаете значение j, то есть 3, load. Если не указано иное, C ++ передается по значению.

У вас будет такая же проблема с глобальной переменной:

int foo;

int returnit(int j)
{
    return j;
}

int main(void)
{
    int j=returnit(foo);

Как вы думаете, какое значение j должно иметь здесь ?! Вам все еще нужно инициализировать переменную некоторым конкретным значением, прежде чем вы сможете передать ее значение в функцию.

0 голосов
/ 01 февраля 2012

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

void load(int& sal)
{
    cout << "your salary: " << endl;
    cin >> sal;
    cout << sal << endl;
}

Обратите внимание на '&' после int в сигнатуре функции.

Также обратите внимание, что вы используете 'salary' в load (), где она не определена. Вместо этого вы должны использовать «sal».

Таким образом, компилятор узнает, что load () получает ссылку на переменную, поэтому, если вы измените ее внутри функции, переменная, отправленная вами в функцию (salary), также изменится.

Сам вызов функции остается прежним.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...