Отговори на тема  [ 31 мнения ]  Отиди на страница Предишна  1, 2, 3  Следваща
Използване на указатели в С 
Автор Съобщение
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Съб Юли 22, 2006 9:50 pm
Мнения: 1638
Мнение 
Явно нещо не съм обяснил както трябва-Имам 2 масива с еднаква размерност.Върху елементите на първия правя някакви математически операции и в последствие копирам масив1 в масив2.Математическите операции са без значение,интересуваше ме работата с поинтери и адресирането(достъпа) до всеки елемент от масива.Аз пиша на асемблер и сега преминавам на С и се уча,та за това питам.

#include <18F448.H>
#include <stdio.h>
#include <math.h>
#include <stddef.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=10000000)
struct period { int data [7];}m;
struct period *p;
struct period1 { int data1 [7];}n;
struct period1 *q;
int i,j;
int t,r;
int value_1;
void main() {
value_1=0x3F;
p=&m;
q=&n;
j=((int)(value_1/0x09));
(*p).data[0]=j;
for(i>=1;i<8;i++){
(*p).data[i]=(((*p--).data[i-1])+j);
(*p++);
};
{
int i; // локална променлива
i=0;
for(i>=0;i<8;i++){
((*q).data1[i])=((*p).data[i]);
};
};
}
Това снощи го съчиних и за сега ми върши работа.Ако някой нейде види че правя грешка- да ме поправи,щото може и да греша.
Благодаря на всички за коментарите,но съм сигурен че ще възникнат и нови въпроси :)


Нед Апр 01, 2007 9:24 am
Профил
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Нед Окт 31, 2004 9:19 pm
Мнения: 4464
Местоположение: Stara Zagora
Мнение 
това с (*p) много грозно. Когато от указател към структура или клас искаш да оперираш с някой от членовете ползвай си -> за тази цел по прегледно е.

Код:
j=((int)(value_1/0x09));
==
j= value_1/0x09;

вярно че когато не си сигурен е по добре да слагаш скоби и явни преобразувания но не трябва да се прекалява защото кода става труден за четене.
Типа на резултата от един израз се определя от първия член в израза. В случая от value_1 което си е int.
Но и float да беше компилатора щеше да си направи неявното преобразуване без забележки.


Нед Апр 01, 2007 9:52 am
Профил
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Пон Юни 05, 2006 1:48 pm
Мнения: 4906
Местоположение: където небето среща земята, ракията е Jameson, а бирата Guinness
Мнение 
Ки4о написа:
int i; // локална променлива
i=0;
for(i>=0;i<8;i++){..................}

Това снощи го съчиних и за сега ми върши работа.Ако някой нейде види че правя грешка- да ме поправи,щото може и да греша.
Благодаря на всички за коментарите,но съм сигурен че ще възникнат и нови въпроси :)


добре де Kи4о, ама ЗАЩО за богa пишеш така???????
откакто се знам се изписа по този начин.....
for(i = 0; i < 8;i++ )

защо ти е това i >= 0 айде сега кажи?!? :x ....може би имаш в предвид нещо ама, ама със сигурност сега се учиш да пишеш на С............. нещо не е у ред постановката.....

_________________
... ако трети ден не ти се работи... това означава, че е сряда !


Нед Апр 01, 2007 11:56 am
Профил
Ранг: Минаващ
Ранг: Минаващ
Аватар

Регистриран на: Вто Ное 16, 2004 4:43 pm
Мнения: 85
Местоположение: София
Мнение 
Доста объркани сметки за разбиране:

Код:
(*p).data[0]=j;

това е добре, първия елемент от масива става равен на j

Код:
for (i >= 1; i < 8; i++) { 

Това ... е странно. По принцип конструкцията на for е:
for (инициализация ; условие -> до кога ще се върти цикъла; какво ще се прави на всяко завъртане на цикъка)
при теб:
инициализация е: i>=1 -> това е израз, който връща 0 или 1 в зависимост от стойноста на i, но не променя стойноста на i. сложен на това място няма никакъв смисъл. Предполагам, че искаш да напишеш i=1;
условие: i<8 -> цикъла ще се върти докато i е по-малко от 8, което е грешно, защото ще адресираш и p->data[7], а за него не си заделил памет. имаш само p->data[0...6]. По-вярно е i<7

Код:
(*p).data[i]=(((*p--).data[i-1])+j);

Това вече е доста нечетимо (като идея) и грешно като записване. Ако го пуснеш на gcc -Wall ми казва:
warning: operation on `p' may be undefined
Операциите ++ и -- са коварни. Трябва да се запознаеш добре преди да ги ползваш.
Предполагам, че искаш да напишеш:
Код:
p-> data [i] = p-> data [i - 1] + j;

(*p).нещоси може да се запише като p->нещоси, но това вече го казаха.


Код:
(*p++);

Тук може да го напишеш само:
Код:
p++;

и ще прави същото, но ... p ще сочи след операцията към незаделена памет.

Копирането бих го направил така (за for-а важат същите забележки):
Код:
int i; // локална променлива
for (i = 0; i < 7; i++) {
   q-> data1 [i] = p-> data [i];
}


Нед Апр 01, 2007 12:24 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Съб Юли 22, 2006 9:50 pm
Мнения: 1638
Мнение 
@danov,мисля че не бъркам в следното :
масива е с 8 елемента:0,1,2,3,4,5,6,7.Ако сложа ограничението до 6 (на практика 7 елемент от масива),тогава как ще адресирам 8-мия елемент ?Че правя грешки-правя,коригирам си грешките и се уча


Нед Апр 01, 2007 1:18 pm
Профил
Ранг: Минаващ
Ранг: Минаващ
Аватар

Регистриран на: Вто Ное 16, 2004 4:43 pm
Мнения: 85
Местоположение: София
Мнение 
Ки4о написа:
@danov,мисля че не бъркам в следното :
масива е с 8 елемента:0,1,2,3,4,5,6,7.Ако сложа ограничението до 6 (на практика 7 елемент от масива),тогава как ще адресирам 8-мия елемент ?Че правя грешки-правя,коригирам си грешките и се уча


Код:
struct period { int data [7];}m;

Това е дефиниция на масив със 7 елемента: 0,1,2,3,4,5,6
Ако искаш да има 8, то го напиши:
Код:
struct period { int data [8];}m;

При дефиниране на масиви се пише не последния индекс, а броя елементи. И се адресира от 0 до n-1.


Нед Апр 01, 2007 1:40 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Пон Юни 05, 2006 1:48 pm
Мнения: 4906
Местоположение: където небето среща земята, ракията е Jameson, а бирата Guinness
Мнение 
Кичо,
for (i = 0; i < 8; i++)
{
}


for (i = 0; i <=7; i++ )
{
}

при двата случая израза в скобите е истина за i = [0..7]
демек
квото си изписал във фор цикъла и го индексираш с променлива "i" ще се индексира със стойности от 0 до 7 включително :!: и после ще излезеш от фор цикъла ..........................................................

_________________
... ако трети ден не ти се работи... това означава, че е сряда !


Нед Апр 01, 2007 1:57 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Нед Окт 31, 2004 9:19 pm
Мнения: 4464
Местоположение: Stara Zagora
Мнение 
И избягвай като начинаещ да пишеш сложни изрази. Трудни са за четене и обикновенно са източник на грешки.

Тук добре са описани станрартните C библиотеки. Свиквай да ги ползваш. Няма смисъл да пишеш вече написан код.
http://www.cplusplus.com/reference/clibrary/
Код:
for (i = 0; i < 7; i++) {
   q-> data1 [i] = p-> data [i];
}


става така
Код:
memcpy(q->data1,p-> data,7);

Kато разбира се трябва да инклуднеш библиотеката в която е дефиниран memcpy().
За конкретния компилатор и процесор си отваряш съответния фаил в случая string.h и гледаш как точно е дефинирана съответната стандартна функция. За процесорите които нямат единно адресно пространсто обикновенно са предоставени няколко варианта за работа с различни варианти на параметрите. Но е добре да свикваш да си ползваш стандартните библиотеки.
За начло прочети описанието на:
cmath (math.h)
cstdio (stdio.h)
cstdlib (stdlib.h)
cstring (string.h)
ctime (time.h)


Нед Апр 01, 2007 2:07 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Вто Дек 14, 2004 1:31 pm
Мнения: 3849
Мнение 
Nikola Kirov написа:

Код:
j=((int)(value_1/0x09));
==
j= value_1/0x09;

вярно че когато не си сигурен е по добре да слагаш скоби и явни преобразувания но не трябва да се прекалява защото кода става труден за четене.
Типа на резултата от един израз се определя от първия член в израза. В случая от value_1 което си е int.
Но и float да беше компилатора щеше да си направи неявното преобразуване без забележки.


В някои ситуации не може да се разчита на компилатора. С КЕИЛ-а имах следния проблем. Кода беше нещо от сорта:
Код:
unsigned long a;
unsigned int b;
....
a = 25E3 * (b - 1);


И докато не го смених на
Код:
a = 25E3 * ((unsigned long)b - 1);


омазваше нещата.


Нед Апр 01, 2007 2:17 pm
Профил WWW
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Нед Окт 31, 2004 9:19 pm
Мнения: 4464
Местоположение: Stara Zagora
Мнение 
преполагам че е имало конкретна причина за да е така.
в първия случай резултата от операцията в скобите е int след което умножаваш по int value. а в втория резултата си е unsigned long. Така че имаш принципна разлика между 2 та записа.


Нед Апр 01, 2007 2:31 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Съб Юли 22, 2006 9:50 pm
Мнения: 1638
Мнение 
Никола,благодаря за съвета.Въпроса който възниква в момента е следния-използвах функцията memcpy,без да съм инклуднал string.h,ползвам само stdio.h,math.h и се получи.Възможно ли е една функция да е в няколко библиотеки ?


Нед Апр 01, 2007 2:51 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Вто Дек 14, 2004 1:31 pm
Мнения: 3849
Мнение 
Моя грешка, стойността беше 625Е3, a нe 25E3. И резултата не прехвьрляше 32-тo бита на unsigned long.
Обаче сега като го тествах вкьщи и двата варианта дават един и сьщ, коректен код на Асемблер. Нещо не си спомням значи. Утре ще видя точно как стояха нещата, бях си коментирал проблема, и ще пиша. В момента бьркам нещо :oops:


Нед Апр 01, 2007 2:58 pm
Профил WWW
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Нед Окт 31, 2004 9:19 pm
Мнения: 4464
Местоположение: Stara Zagora
Мнение 
някои компилатори си инклудват стандартните библиотеки по подразбиране. Може такъв да се случая. Няма начин да е дефинирана в 2 библиотеки. Пък като се съмняваш отваряш си съответния h и гледаш.


Нед Апр 01, 2007 3:27 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Чет Окт 07, 2004 1:22 pm
Мнения: 1949
Местоположение: София
Мнение 
Като гледам става въпрос за CCS - там нещата с инклудовете и вградените библиотеки е много откачена - специално това с memcpy преди време ми правеше проблеми, без да инклудвам string.h се компилира кода и работи, с инклудването на тоя хедър се компилира нещо съвсем различно (съдя по листинга), но пак работи. Освен това в много от .h файловете предоставени от CCS компилатора ми дава грешка (обикновено, че функцията която е описана там не може да бъде намерена от линкера)...взех много да се мръщя на тоя компилатор, ползвам го само за малки проектчета под 8K FLASH. В един проект имах доста такива манипулации на памет, работа със стрингове, беше за 18F452, работеше що годе добре, реших да ъпдейтна CCS с по-нова версия и просто се изумих какви глупости имаше в листинга...реших си проблема с Hi-Tech


Нед Апр 01, 2007 6:16 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Съб Юли 22, 2006 9:50 pm
Мнения: 1638
Мнение 
@Predator_MF,кое ти е правило по-малко проблеми CCS или HiTech?Да питам дорде съм в началото.Някъде беше писано из форума повече за двете среди но не мога да го открия.Хванах CCS -понеже имам впечатлението,че повечето от членовете на форума (които пишат за ПИК) ползват този компилатор ,та ако имам нещо да питам - ще има нялой да отговори :)


Нед Апр 01, 2007 7:44 pm
Профил
Покажи мненията от миналия:  Сортирай по  
Отговори на тема   [ 31 мнения ]  Отиди на страница Предишна  1, 2, 3  Следваща

Кой е на линия

Потребители разглеждащи този форум: 0 регистрирани и 2 госта


Вие не можете да пускате нови теми
Вие не можете да отговаряте на теми
Вие не можете да променяте собственото си мнение
Вие не можете да изтривате собствените си мнения
Вие не можете да прикачвате файл

Търсене:
Иди на:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group.
Designed by ST Software for PTF.
Хостинг и Домейни