Проблемы С Глобальным Массивом

  • Автор темы Автор темы SchwarzeWolfin
  • Дата начала Дата начала
S

SchwarzeWolfin

есть проект на Visual Studio 2008, в файле matix.h объявляю массивы

Код:
const int M = 4;
float T[M][M],R1[4][4],R2[4][4],R3[4][4],W[4][4],V1[4][4];

extern float ttt[2];
float xx1, xx2, yy1, yy2;
float a1, a2, b1, b2;
float ms1,ms2;
float tn_x,tn_y,tn_z,vr_x,vr_y,vr_z,aA,bB,cC;



void prR2(float vx, float vz, float c[M][M]);
void prR3(float vx, float vy, float vz, float c[M][M]);
void prW(float a,float c[M][M]);

void times(float a[M][M], float b[M][M], float c[M][M]);
void timesVM(float a[M], float b[M][M], float c[M]);
void set(float a[M][M], float b[M][M]);
void homogen(float a[M], float b[M]);
void cortesian(float b[M], float a[M]);
void makeHomogenVec(float x, float y, float z, float c[M]);
void unit(float e[M][M]);
void move(float Tx, float Ty, float Tz, float c[M][M]);
void rotate(float phi, float c[M][M]);
void scale(float S, float c[M][M]);

потом я в файле Form1.h пишу например T[0][0] = 5; при этом значение элемента массива вообще никак не изменяется. но если таким же образом объявить просто переменную типа float (не массив), то всё нормально работает. подскажите пожалуйста, как исправить
 
но если таким же образом объявить просто переменную типа float (не массив), то всё нормально работает
Но не должно.
Код, который размещается в хедерах вообще не компилируется.

Но он будет скопилирован, если хедер будет включен в единицу компиляции (.cpp файл).
Поэтому глобальные переменные в хедерах объявлять вообще ненадо.

если ты объявишь глобальную переменную в 1.h, подключишь его в 2.cpp и 3.cpp - то получишь ошибку линковки, скорее всего.

Посмотри в сторону ключевого слова extern.

-----------
То, что выше, касалось объявления переменных. Теперь по инициализации.
потом я в файле Form1.h пишу например T[0][0] = 5;
Это вообще не должно работать. Смотри, гипотетически, ты инициализируешь одну и ту же глобальную переменную в нескольких файлах, что должен делать компилятор в этом случае? - какое значение ей присвоить?
Никогда так не делай. Инициализацию переменных вноси в код функций.

Инициализировать сразу можно только глобальные константы.
 
спасибо за ответ. а изменение значения элементов массива как раз в функции и описано - в обработчике загрузки формы (FormLoad вроде), что именно здесь неверно?
 
Я не вижу кода, который не работает (если возможно - повторите ошибку на более простом примере {чтобы была только одна функция и один массив}).

И прикрепите код полностью. (тут самое главное раздел include, а вы его и вовсе не прикрепляли).

Если не хочется долго искать ошибку, попробуйте отказаться от глобальных переменных вовсе - это нормальная практика.

Еще важно знать в каком месте описана функция.

Я вроде как пытаюсь повторить твою ошибку, но мне об ошибке компилятор сообщает (все как я описывал выше):

файл 3.h:
Код:
int a;
файл 1.cpp:
Код:
#include "3.h"
файл 2.cpp:
Код:
#include "3.h"
int main() {
a = 1000;
}

Компилирую:
rrrfer@linux-2oyq:~/project> g++ 1.cpp 2.cpp -o main
/tmp/ccyrjX8E.o:(.bss+0x0): multiple definition of `a'
/tmp/ccyKLNcO.o:(.bss+0x0): first defined here
collect2: error: ld returned 1 exit status
rrrfer@linux-2oyq:~/project>

Причины я описал выше - в каждой единице компиляции получается своя копия глобальной переменной.
Потому что перед компиляцией происходит препроцессорная обработка, при которой все директивы include без разбора заменяются на текст файлов (которые указаны в директиве - в данном случае 3.h).

В результате после препроцессорной обработки имеем:

файл 1.cpp:
Код:
int a;
файл 2.cpp:
Код:
int a;
int main() {
a = 1000;
}

Каждый модуль (единица компиляции) компилируется отдельно в объектный файл, и все окей. Но потом наичнает работать линкер, который из объектных файлов пытается построить исполняемый файл. И тут линкер замечает, что в исполняемом файле выходит 2 глобальных переменных с одним именем - и мы получаем "странную ошибку", пример которой я привел выше.

А как делаете Вы? - как у вас получилось это: "но если таким же образом объявить просто переменную типа float (не массив), то всё нормально работает. "
 
Мы в соцсетях:

Обучение наступательной кибербезопасности в игровой форме. Начать игру!