Модераторы: bsa

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Не вижу ошибку 
:(
    Опции темы
Compositum
Дата 12.6.2011, 09:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Senior developer
**


Профиль
Группа: Awaiting Authorisation
Сообщений: 430
Регистрация: 6.1.2008
Где: Санкт-Петербург

Репутация: нет
Всего: 1



Си (C89):
Код

#include<stdio.h>

static struct customer{
    char *name;
    int age;
};

void xmsg(static struct customer cust){    
    printf("%s,\t%i\n", cust.name, cust.age);
}
    
main(){    
    struct customer user;    
    user.name = "Andrey";
    user.age = 33;
    xmsg(user);
    return 0;
}

При компиляции получаю ошибку, текст которой мне не способствует в понимании того, что именно не понравилось компилятору:
Цитата(Терминал)

bush@mycomp:~/training/c/c89/mytests$ gcc x.c -o x.out
x.c:6:1: warning: useless storage class specifier in empty declaration
x.c:8:34: error: storage class specified for parameter ‘cust’
bush@mycomp:~/training/c/c89/mytests$ 


Это сообщение отредактировал(а) Compositum - 12.6.2011, 09:22
PM   Вверх
triclosan
Дата 12.6.2011, 09:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 515
Регистрация: 18.8.2006

Репутация: 2
Всего: 12



Зачем тут 
Цитата(Compositum @  12.6.2011,  09:03 Найти цитируемый пост)
void xmsg(static struct customer cust){    

static ?
PM MAIL   Вверх
Compositum
Дата 12.6.2011, 09:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Senior developer
**


Профиль
Группа: Awaiting Authorisation
Сообщений: 430
Регистрация: 6.1.2008
Где: Санкт-Петербург

Репутация: нет
Всего: 1



подправил код и добавил комментарии, чтобы пояснить ход своих соображений:
Код

#include<stdio.h>
/*Ограничиваю область видимости структуры
текущим файлом (не хочу, чтобы к ней имели
доступ извне)
*/
static struct customer{
        char *name;
        int age;
};
/*
Поскольку структура, передаваемая в качестве
параметра имеет ограниченную область видимости -
такую же область назначаю и функции, в параметре
которой используется эта структура. При этом
гарантирую, что объект, переданный параметром
не будет изменён - помечаю параметр как static
*/
static void xmsg(static struct customer cust){    
    printf("%s,\t%i\n", cust.name, cust.age);
}

/*
Точка входа
*/
main(){    
    struct customer user;    
    user.name = "Andrey";
    user.age = 33;
    xmsg(user);
    return 0;
}

Результат компиляции:
Цитата(Терминал)

bush@mycomp:~/training/c/c89/mytests$ gcc x.c -o x.out
x.c:9:1: warning: useless storage class specifier in empty declaration
x.c:18:41: error: storage class specified for parameter ‘cust’
bush@mycomp:~/training/c/c89/mytests$


Это сообщение отредактировал(а) Compositum - 12.6.2011, 09:48
PM   Вверх
triclosan
Дата 12.6.2011, 09:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 515
Регистрация: 18.8.2006

Репутация: 2
Всего: 12



Цитата(triclosan @ 12.6.2011,  09:28)
Зачем тут 
Цитата(Compositum @  12.6.2011,  09:03 Найти цитируемый пост)
void xmsg(static struct customer cust){    

static ?

когда нужно const
PM MAIL   Вверх
Compositum
Дата 12.6.2011, 10:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Senior developer
**


Профиль
Группа: Awaiting Authorisation
Сообщений: 430
Регистрация: 6.1.2008
Где: Санкт-Петербург

Репутация: нет
Всего: 1



Цитата(triclosan @ 12.6.2011,  09:58)
Цитата(triclosan @ 12.6.2011,  09:28)
Зачем тут 
Цитата(Compositum @  12.6.2011,  09:03 Найти цитируемый пост)
void xmsg(static struct customer cust){    

static ?

когда нужно const

Спасибо, это я ошибся - конечно же нужен static. Исправил.
Однако при компиляции всё ещё получаю ошибку:
Цитата(Терминал)

bush@mycomp:~/training/c/c89/mytests$ gcc x.c -o x.out
x.c:9:1: warning: useless storage class specifier in empty declaration
bush@mycomp:~/training/c/c89/mytests$ 



PM   Вверх
triclosan
Дата 12.6.2011, 10:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 515
Регистрация: 18.8.2006

Репутация: 2
Всего: 12



покажите код пожалуйста
PM MAIL   Вверх
Compositum
Дата 12.6.2011, 10:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Senior developer
**


Профиль
Группа: Awaiting Authorisation
Сообщений: 430
Регистрация: 6.1.2008
Где: Санкт-Петербург

Репутация: нет
Всего: 1



Цитата(triclosan @ 12.6.2011,  10:29)
покажите код пожалуйста

Код

#include<stdio.h>
/*Ограничиваю область видимости структуры
текущим файлом (не хочу, чтобы к ней имели
доступ извне)
*/
static struct customer{
        char *name;
        int age;
};
/*
Поскольку структура, передаваемая в качестве
параметра имеет ограниченную область видимости -
такую же область назначаю и функции, в параметре
которой используется эта структура. При этом
гарантирую, что объект, переданный параметром
не будет изменён - помечаю параметр как const
*/
static void xmsg(const struct customer cust){    
    printf("%s,\t%i\n", cust.name, cust.age);
}

/*
Точка входа
*/
main(){    
    struct customer user;    
    user.name = "Andrey";
    user.age = 33;
    xmsg(user);
    return 0;
}


Добавлено @ 10:33
Если я объявлю структуру так:
Код

static struct customer{
        char *name;
        int age;
}x;

т.е. определю и некую переменную с именем 'x', то всё компилируется и работает нормально, несмотря на то, что 'x' я нигде более не использую...
Однако мне бы не хотелось объявлять в коде ненужные мне переменные...
Версия используемого мною компилятора: gcc version 4.5.2 (Ubuntu/Linaro 4.5.2-8ubuntu4)

Это сообщение отредактировал(а) Compositum - 12.6.2011, 10:37
PM   Вверх
asmdzen
Дата 12.6.2011, 11:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата



**


Профиль
Группа: Участник
Сообщений: 345
Регистрация: 28.11.2010

Репутация: 3
Всего: 5



потому что вы просто объявляете тип данных, зачем вам статик писать? его можно писать только перед переменными, а у вас объявление типа, когда вы "х" добавляете это уже и переменная.
PM MAIL   Вверх
Compositum
Дата 12.6.2011, 11:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Senior developer
**


Профиль
Группа: Awaiting Authorisation
Сообщений: 430
Регистрация: 6.1.2008
Где: Санкт-Петербург

Репутация: нет
Всего: 1



Цитата(asmdzen @ 12.6.2011,  11:33)
потому что вы просто объявляете тип данных, зачем вам статик писать? его можно писать только перед переменными, а у вас объявление типа, когда вы "х" добавляете это уже и переменная.

А вон оно как... Спасибо, я-то думал, что структуре так же можно назначать область видимости (в C# точно можно)... Т.е. в C (C89/C99) помечать как static можно только переменные и функции, а структуры, объединения, перечисления нельзя? Я не нашёл информации по этому вопросу ни у Шильдта, ни у Ритчи...
PM   Вверх
borisbn
Дата 12.6.2011, 11:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 21
Всего: 135



Цитата(Compositum @  12.6.2011,  11:40 Найти цитируемый пост)
static можно только переменные и функции

просто функции объявлять static не имеет смысла, т.к. они и так static.
и потом, static не определяет область видимости. static говорит о том, в какой памяти выделять переменную - в статической или на стеке. 
Например:
Код

void foo() {
    static bool first = true;
    if ( first ) {
        first = false;
        ...
    }
}

доступ к этой static-переменной возможен только из этой функции, а память будет выделена не на стеке, в глобальной памяти. И её значение не будет теряться при выходе из функции.
А объявлять глобальные переменные static тоже не имеет смысла, т.к. они и так выделяются в статической памяти.


Это сообщение отредактировал(а) borisbn - 12.6.2011, 11:58


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
asmdzen
Дата 12.6.2011, 12:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата



**


Профиль
Группа: Участник
Сообщений: 345
Регистрация: 28.11.2010

Репутация: 3
Всего: 5



Цитата(borisbn @  12.6.2011,  11:55 Найти цитируемый пост)
А объявлять глобальные переменные static тоже не имеет смысла, т.к. они и так выделяются в статической памяти.



Цитата(Compositum @  12.6.2011,  09:03 Найти цитируемый пост)
Си (C89)

static перед глобальными переменными ограничивает область видимости текущим файлом.

PM MAIL   Вверх
volatile
Дата 12.6.2011, 12:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2107
Регистрация: 7.1.2011

Репутация: 16
Всего: 85



Цитата(borisbn @  12.6.2011,  11:55 Найти цитируемый пост)
просто функции объявлять static не имеет смысла, т.к. они и так static.

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

Цитата(borisbn @  12.6.2011,  11:55 Найти цитируемый пост)
А объявлять глобальные переменные static тоже не имеет смысла, т.к. они и так выделяются в статической памяти.

тоже самое.
статик перед глобальными переменными, не определяет способ размещения (в статической или динамической), а определяет область видимости для переменной.

вобщем и перед функциями, и перед глобальными переменными, статик имеет определенный смысл.
например мы можем иметь несколько одноименных функций в программе, в каждом модуле (единице трансляции) своя
static int func ();
без слова static, не скомпилируется, линкер будет жаловаться. int func (); alredy have a body
Тоже самое с глобальными переменными.


PM MAIL   Вверх
Compositum
Дата 12.6.2011, 12:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Senior developer
**


Профиль
Группа: Awaiting Authorisation
Сообщений: 430
Регистрация: 6.1.2008
Где: Санкт-Петербург

Репутация: нет
Всего: 1



Цитата(borisbn @ 12.6.2011,  11:55)
Цитата(Compositum @  12.6.2011,  11:40 Найти цитируемый пост)
static можно только переменные и функции

просто функции объявлять static не имеет смысла, т.к. они и так static.
и потом, static не определяет область видимости. static говорит о том, в какой памяти выделять переменную - в статической или на стеке. 
Например:
Код

void foo() {
    static bool first = true;
    if ( first ) {
        first = false;
        ...
    }
}

доступ к этой static-переменной возможен только из этой функции, а память будет выделена не на стеке, в глобальной памяти. И её значение не будет теряться при выходе из функции.
А объявлять глобальные переменные static тоже не имеет смысла, т.к. они и так выделяются в статической памяти.

Вы меня не поняли, я говорил не о локальных переменных, объявленных как static... smile Да и неправы вы насчёт того, что функции по умолчанию объявляются как static, ибо в C применительно к функциям оно является указанием на то, что функция/глобальная переменная должна быть скрытой от посторонних глаз... Поясню на примере.

Пример:
Предположим, что я написал некий файл z.c, в котором определил переменную и функцию:
Код

//файл z.c
#include<stdio.h>

char ch[] = "Hello World";
void mymsg(){    
    printf("I like C lang.\n");
}

обратите внимание - переменная и функция определены не как static.
Теперь я пишу файл y.c, в коде которого хочу воспользоваться переменной ch и функцией mymsg:
Код

//файл y.c
#include<stdio.h>
/*
Переменная и функция определены в др.
файле, но доступны и в этом
*/
extern char ch[];
extern void mymsg();

int main(){
    printf("Message: %s\n", ch);
    mymsg();
    return 0;
}

Результат:
Цитата(Терминал)

bush@mycomp:~/training/c/c89/mytests$ gcc z.c y.c -o w.out
bush@mycomp:~/training/c/c89/mytests$ ./w.out 
Message: Hello World
I like C lang.
bush@mycomp:~/training/c/c89/mytests$

Как видим - всё замечательно работает.
Но в том случае, если я захочу, чтобы какие-то глобальные переменные и/или функции, определённые мною в файле z.c не были доступны вне этого файла (т.е. хочу спрятать их от посторонних глаз, ибо они - для внутреннего использования в рамках файла z.c), то я должен помечать их атрибутом static. В этом случае из др. файлов получить доступ к этим элементам не смогут (как и требуется). Модифицирую файл z.c (файл y.c оставляю прежним):
Код

//файл z.c
#include<stdio.h>

static char ch[] = "Hello World";
static void mymsg(){    
    printf("I like C lang.\n");
}

Теперь компилирую:
Цитата(Терминал)

bush@mycomp:~/training/c/c89/mytests$ gcc z.c y.c -o w.out
/tmp/ccFTzLb2.o: In function `main':
y.c:(.text+0xa): undefined reference to `ch'
y.c:(.text+0x21): undefined reference to `mymsg'
collect2: ld returned 1 exit status
bush@mycomp:~/training/c/c89/mytests$ 

Как видим - компилятор "не находит" объекты `ch' и `mymsg' - оно и понятно, я же объявил их как static, ограничив тем самым область их видимости границами файла z.c).
Возвращаясь к теме настоящего топика - когда я говорил о том, что хочу структуру определить как static, то имел в виду, что её область видимости должна быть такой же как у глобальной переменной или функции, объявленных как static - т.е. чтобы структура была не видна за границами файла.


PM   Вверх
volatile
Дата 12.6.2011, 12:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2107
Регистрация: 7.1.2011

Репутация: 16
Всего: 85



Цитата(Compositum @  12.6.2011,  12:36 Найти цитируемый пост)
чтобы структура была не видна за границами файла.

Compositum, определите структуру в *.с, (не в *.h), и она не будет видима нигде кроме этого файла.

PM MAIL   Вверх
borisbn
Дата 12.6.2011, 12:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 21
Всего: 135



да, да, да... совсем забыл про extern. он и делает возможность "увидеть" глобальные переменные.
Старый стал, начал забывать Си smile  Sorry smile


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Для новичков"
JackYF
bsa

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

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


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.0718 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.