[완료]퀵 소트 정렬 문제입니다.

아리망의 이미지

안녕하세요?
다름이 아니라 gcc로 전화번호관리 프로그램 만드는 과제가 있습니다.
그래서 책보고 열심히 만들었는데 정작 퀵 정렬시에 사용되는 compare 함수때문에 막히게 되었습니다.

책의 예제도 보고 인터넷도 찾아보고 했는데 정작 제가 원하는 구조체에서 문자렬 비교하는 부분이 없네요....
어렵게 어렵게 하나 찾았는데 원하는 정렬을 시켰는데 warning이 뜨네요....

main.c: In function ‘compare_stdno’:
main.c:87: warning: initialization discards qualifiers from pointer target type
main.c:88: warning: initialization discards qualifiers from pointer target type
main.c: In function ‘compare_name’:
main.c:102: warning: initialization discards qualifiers from pointer target type
main.c:103: warning: initialization discards qualifiers from pointer target type

이렇게요... warning 없애는 방법 없을까요?
군대 갔다오고 복학하니깐 C언어 따라갈려니 너무 힘드네요...
휴~

아래는 소스 코드입니다. 잡다하게 많은데 퀵 정렬(qsort)에 필요한 compare 함수는 main.c 에 있습니다.

/* phonerec.h */
#ifndef _PHONEREC_H
#define _PHONEREC_H
struct _phoneRec;
typedef struct _phoneRec
{
char grade[2];
char dept[3];
char stdno[9];
char name[21];
char phoneno[15];
} phoneRec;
typedef phoneRec* p_phoneRec;

#define MAX_TABLESIZE 50

void printRec(p_phoneRec tempRec);
void printTable();
void freeTable();
#endif

/* phonerec.c */
#include "phonerec.h"
#include
#include
#include

extern int tableSize;
extern p_phoneRec* phoneTable;

void printRec(p_phoneRec tempRec)
{
printf("%1s %2s %8s %20s %s\n", tempRec->grade, tempRec->dept,
tempRec->stdno, tempRec->name, tempRec->phoneno);

}

void printTable()
{
int i;
for(i=0; i {
printRec(phoneTable[i]);
}
}

void freeTable()
{
int i;
for(i=0; i {
free(phoneTable[i]);
}
free(phoneTable);
tableSize=0; phoneTable=NULL;
}

/* readrec.h */
#ifndef _READREC_H
#define _READREC_H

int readTable();

#endif

/* readrec.c */
#include "phonerec.h"
#include #include

extern int tableSize;
extern p_phoneRec* phoneTable;

int readRec(p_phoneRec newRec)
{
int res;
res = scanf("%1c %2c %8c %20c %s\n", &newRec->grade, newRec->dept,
&newRec->stdno, newRec->name,
newRec->phoneno);
newRec->grade[1] = 0;
newRec->dept[2] = 0;
newRec->stdno[8] = 0;
newRec->name[20] = 0;
return res;
}

int readTable()
{
int i, count = 0;
phoneRec tempRec;
p_phoneRec newRec;
while(readRec(&tempRec) != EOF)
{
newRec = (p_phoneRec)malloc(sizeof(phoneRec));
if(newRec == NULL)
{
printf("Error: memory allocation error\n");
exit(1);
}
*newRec = tempRec;
phoneTable[count] = newRec;
count++;
}
return count;
}

/* main.c */
#include "phonerec.h"
#include "readrec.h"
#include
#include
#include
#include

int tableSize = 0; // Current number of Records
p_phoneRec* phoneTable; // pointer to Table

/* 퀵정렬 compare함수*/
int compare_stdno(const void *ap, const void *bp)
{
/* 아래 주석부분로 하니깐 값은 나오는데 정렬은 안되어서 나옵니다. */
//return strcmp(((struct _phoneRec *)ap)->stdno,
// ((struct _phoneRec *)bp)->stdno);

const struct _phoneRec **a = ap;
const struct _phoneRec **b = bp;
char a1[9], b1[9];
strcpy(a1, (*a)->stdno);
strcpy(b1, (*b)->stdno);
return strcmp(a1,b1);

}

int compare_name(const void *ap, const void *bp)
{

//return strcmp(((struct _phoneRec *)ap)->name,
// ((struct _phoneRec *)bp)->name);

const struct _phoneRec **a = ap;
const struct _phoneRec **b = bp;
char a1[21], b1[21];
strcpy(a1, (*a)->name);
strcpy(b1, (*b)->name);
return strcmp(a1,b1);
}

void print_help()
{
printf("phonebook [-h] [-s name|stdno] < PHONE_FILE \n");
printf(" -h print this help... \n");
printf(" -s name|stdno sort by name or stdno. \n");
}

int main(int argc, char *argv[])
{
char c, sortkey = 'r';
while((c=getopt(argc,argv,"hs:"))!=-1)
{
switch(c) {
case 'h':
print_help();
exit(0);
case 's':
if(strcmp(optarg, "name") == 0)
sortkey = 'n';
else if(strcmp(optarg, "stdno") == 0)
sortkey = 's';
break;
case '?':
fprintf(stderr, "Unknown option '-%c'. \n", optopt);
print_help();
exit(1);
}
}
phoneTable = (p_phoneRec *)calloc(sizeof(p_phoneRec), MAX_TABLESIZE);
tableSize = readTable();

switch(sortkey)
{
case 'n':
qsort(phoneTable, tableSize, sizeof(p_phoneRec), compare_name);
break;
case 's':
qsort(phoneTable, tableSize, sizeof(p_phoneRec), compare_stdno);
break;
case 'r':
default:
break;
}
printTable();
freeTable();
}

bushi의 이미지

int compare_name(const void *ap, const void *bp)
{
    struct _phoneRec *a = *(struct _phoneRec **)ap;
    struct _phoneRec *b = *(struct _phoneRec **)bp;
    char *an = a->name;
    char *bn = b->name;
    return strcmp(an, bn);
}

정도가 미관상 좋은 것 같고요.

strcmp() 를 문의하시는 것 같지는 않지만...

Linus Torvalds 가 빡세게 구겨넣은 C,

int strcmp(const char *cs, const char *ct)
{
    signed char __res;
 
    while (1) {
        if ((__res = *cs - *ct++) != 0 || !*cs++)
            break;
    }
 
    return __res;
}

x86 용 asm,

int strcmp(const char * cs, const char * ct)
{
    int d0, d1;
    register int __res;
    __asm__ __volatile__(
            "1:\tlodsb\n\t"
            "scasb\n\t"
            "jne 2f\n\t"
            "testb %%al,%%al\n\t"
            "jne 1b\n\t"
            "xorl %%eax,%%eax\n\t"
            "jmp 3f\n"
            "2:\tsbbl %%eax,%%eax\n\t"
            "orb $1,%%al\n"
            "3:"
            :"=a" (__res), "=&S" (d0), "=&D" (d1)
            :"1" (cs),"2" (ct)
            :"memory");
    return __res;
}
winner의 이미지

const p_phoneRec *a = ap, *b = bp;
/* _phoneRec * const *a = ap, * const *b = bp; */
/* _phoneRec const * const *a = ap, * const *b = bp; */
/* _phoneRec * const * const a = ap, * const * const b = bp; */
/* _phoneRec const * const * const a = ap, * const * const b = bp; */

return strcmp((*a)->stdno, (*b)->stdno);

pointer 에 const 가 붙는 위치는 참 많습니다.
다양한 의미를 포함하면서...

아리망의 이미지

두분께서 올린식 방식대로 하니 둘다 warning없이 되네요..
정말 감사합니다. 군대가기 전에도 포인터 때문에 고생했는데 지금도 고생이네요....
시험 끝나고 공부 열심히 해야겠어요....
그럼 좋은 하루되시길...

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.