עבור לתוכן

הגדרת טיפוס ב typedef ב C

Featured Replies

פורסם

לפני שאתה קופץ לקלט מהמשתמש, קודם תבדוק את הפונקציה שמדפיסה בצורה יותר פשוטה, כמו שבדקת את הפונקציות הקודמות. רק אחרי שאתה בטוח שהיא עובדת, תוסיף את הקלט מהמשתמש.

חוץ מזה, פונקציה צריכה להיות דבר מוגדר היטב, ועדיף שלא תהיה תלויה בדברים חיצוניים. פונקציה בשם print_set, הגיוני שהיא תקבל קבוצה כפרמטר ותדפיס אותה - ולא תתעסק בדברים כמו קלט מהמשתמש.

  • תגובות 126
  • צפיות 11k
  • נוצר
  • תגובה אחרונה
פורסם
  • מחבר

הפונקציה מדפיסה בסדר.

אני עובד עם הקומפיילר צעד צעד בתכנית ובשום פעולה אני לא מגיע לתאים שבפעולת הדפסה זה מדפיס לי את המספרים שבפנים.

ותמיד בקריאה הראשונה להדפסה זה מדפיס לי את אותם מספרים למשל קבוצה a זה ידפיס לי בלופ הראשון בנוסף למספרים שהוא אמור להדפיס 86,87 ואם אני מכניס קלט לקבוצה b הוא מוסיף לי 78,79 ואז אם אני מבקש שוב שידפיס את a הוא מוסיף לי 10,11,12,86,87

ואין לי מושג למה זה קורה הרי אני לא מגיע לתאים האלה בכלל וגם בזמן הריצה בקומפיילר התאים האלה שווים ל 0 .

אני כבר לא יודע מה לבדוק....

פורסם
  • מחבר

בעיקרון כל פעולות ה set אמורות להיות בקובץ נפרד מה- main.



#include <stdio.h>

#include <string.h>

#include <stdlib.h>

#define SIZE 16

typedef unsigned char set[SIZE];

set A,B,C,D,E,F;

void read_set();

void print_set();

void union_set();

void intersect_set();

void sub_set();

set* checkname();

int checkbit();

struct{

char *name;

set *s;

}sets[]={

{"a",&A},

{"b",&B},

{"c",&C},

{"d",&D},

{"e",&E},

{"f",&F},

{"A",&A},

{"B",&B},

{"C",&C},

{"D",&D},

{"E",&E},

{"F",&F},

{"#",NULL}

};

 

void setbit(set *s, int i){

char b=0;

int j;

j=i;

B|=1;

i=i%8;

b<<=i;

j=j/8;

*s[j]|=b;

}

 

int checkbit(set *s,int num){

char b=0;

int i;

i=num;

i=i/8;

num=num%8;

B|=*s[i];

if(b>>num&1==1){

return 1;

}else{

return 0;

}

}

set* checkname(){

char *a,*b;

int i=0;

a=sets[i].name;

b=strtok(NULL," ,");

while(strcmp(b,a)!=0&&i<=11){

i++;

a=sets[i].name;

}

if(strcmp(b,a)!=0){

printf("No such group\n");

return 0;

}else{

return sets[i].s;

}

return 0;

}

 

 

void func(char *s){

if(strcmp(s,"read_set")==0)

{

read_set();

return;

}

if(strcmp(s,"print_set")==0)

{

print_set();

return;

}

if(strcmp(s,"union_set")==0)

{

union_set();

return;

}

if(strcmp(s,"intersect_set")==0)

{

intersect_set();

return;

}

if(strcmp(s,"sub_set")==0)

{

sub_set();

return;

}

printf("No such command\n");

return ;

}

 

 

void read_set(){

int x=0,i=0,j=0;

char *y,*c,*z;

y=strtok(NULL,",");//group name from string

c=sets[i].name; //group name from sets

while(strcmp(y,c)!=0&&i<=11){//cheak if the name equal

i++;

c=sets[i].name;

}

if(strcmp(y,c)!=0){

printf("No such group\n");

return;

}else{

z=strtok(NULL,",");//find num char

x=strtol(z,NULL,0);//convert to int

while(x!=-1&&x<=127){//-1=end of string

setbit(sets[i].s,x);

z=strtok(NULL,",");

x=strtol(z,NULL,0);

}

if(x>127){

printf("%d is out of range\n",x);

return;

}

}

}

void print_set(){

set *b;

int k=0,j=0;

b=checkname();//b-point to the group

for(int i=0;i<128;i++){

if(checkbit(b,i)==1){

printf("%d,",i);

k=1;

j++;

if(j==15){

printf("\n");

}

}

}

if(k==0){

printf("the group is empty/n");

}

printf("\n");

}

void union_set(){

set *a,*b,*c;

a=checkname();

b=checkname();

c=checkname();

for(int i=0;i<=12;i++){

*c[i]=*a[i]|*b[i];

}

return;

}

 

 

int main(){

int i=1;

while(i==1){

char g[100];

fgets(g,100,stdin);

g[strlen(g) - 1] = '\0';

char *s=strtok(g," ");

if(strcmp(s,"halt")==0){

break;

}

func(s);

}

return 0;

}



פורסם

ואיפה אתה מאתחל את כל ה-setים? להזכירך, כשאתה מגדיר משתנה אז הוא מכיל ערך אקראי, לא 0.

פורסם
  • מחבר

יש דרך לאתחל את המערך ב- ?


typedef unsigned char set[SIZE];

פורסם
  • מחבר

עשיתי איתחול למערך בפונקציה read_set וזה עובד. אבל אם אני שוב קורא קבוצה אחרת ואז מדפיס את הקבוצה הראשונה זה מוסיף לי מדספרים להדפסה.

פורסם

אז זה אומר שיש לך דריכות אחרות.

ניסית לעשות תכנית בדיקה פשוטה שיוצרת שתי קבוצות, מוסיפה להם איברים ואז מדפיסה אותם, בלי שום קלט מהמשתמש? כי כמו שכבר אמרתי, הבעיה שלך היא בעיקר שאתה מתחיל מדבר מאוד מסובך, במקום לבנות את התכנית ואת הפונקציות שלך שלב אחר שלב. את הקלט מהמשתמש תשמור לסוף.

פורסם

יש דרך לאתחל את המערך ב- ?


typedef unsigned char set[SIZE];

אם SIZE ידוע בזמן קומפילציה אז כן. אחרת תצטרך להקצות דינמית באמצעות malloc.

פורסם

^^ לא נראה לי שהבנת נכון, הגודל שלו כן קבוע, הוא פשוט רצה לאתחל את המערך בזמן ההגדרה.

ב-typedef עצמו אי אפשר, אבל בהגדרה של המשתנים אפשר, לדוגמה ככה:

set A = {0};

פורסם

אז כמובן.

כל המטרה של typedef הוא לקצר שמות טיפוסי משתנים או לתת להם שם אינפורמטיבי יותר.

פורסם
  • מחבר

בדקתי את הבדיקת ביט וכתיבת ביט והדפסת ביט והם עובדות

הבעיה היא כנראה בread_set אם אני נותן פקודות כאלה למשל:

read_set a,1,2,3,4,-1

print_set a

זה מדפיס לי 1,2,3,4

אבל אם אני נותן פקודות כאלה:

read_set a,1,2,3,4,-1

read_set b,5,6,7,-1

print_set a

אז אני אקבל 1,2,3,4,14,15,16

ואת b הוא ידפיס בסדר...

פורסם

אז תדבג את התכנית, לך צעד אחר צעד, בכל צעד תסתכל בדיוק על A ותראה בדיוק מה הוא מכיל (אפשר לעשות את זה באמצעות add watch), וככה תוכל למקם בדיוק את הנקודה שבה כותבים בטעות ל-A.

פורסם
  • מחבר

לא מוצא שמשהו משנה את הקבוצה...

זה קורה רק שאני מכניס קבוצה חדשה, אם אני עושה שינוי לאותה קבוצה הכל עובד תקין.

יש פה משהו שלדעתך יכול לגרום לשינו בקבוצה אחרת או באיתחול שלה(אולי פויינטר או משהו...)



void read_set(){

int x=0,i=0,j=0,k=0;

char *y,*c,*z;

set *s;

y=strtok(NULL,",");//group name from string

c=sets[i].name; //group name from sets

while(strcmp(y,c)!=0&&i<=11){//cheak if the name equal

i++;

c=sets[i].name;

}

if(strcmp(y,c)!=0){

printf("No such group\n");

return;

}else{

z=strtok(NULL,",");//find num char

x=strtol(z,NULL,0);//convert to int

s=sets[i].s;

while(k<=12){//Initialize the group

*s[k]=0;

k++;

}

while(x!=-1&&x<=127){//-1=end of string

setbit(s,x);//set the bit

z=strtok(NULL,",");

x=strtol(z,NULL,0);

}

if(x>127){

printf("%d is out of range\n",x);

return;

}

}

}

פורסם

למה אין לך פשוט פונקציה שמאפסת את הקבוצה?

למה כשאתה מאפס את הקבוצה אתה מאפס רק את תאים 0 עד 12 במערך? מאיפה בכלל מגיע 12?

למה אתה לא משתמש בלולאת for?

בבירור בנקודה כלשהי בתכנית הקבוצה משתנה - בזמן הקריאה, בזמן ההדפסה, איפשהו. בגלל זה אני ממליץ לעקוב אחרי התכנית שלב אחר שלב, לשים breakpoints בכל מיני נקודות מפתח ובכל אחת מהן להסתכל בדיוק על התוכן של A.

ארכיון

דיון זה הועבר לארכיון ולא ניתן להוסיף בו תגובות חדשות.

דיונים חדשים