结构体和链表

结构体

 结构体定义与声明

一般形式:

struct Student
{
    int id;
    float score;
    char name[20];
};

通过struct关键字来声明结构体变量 

结构体变量的操作

访问结构体成员使用 . 运算符,如 student.id。 

结构体变量可以通过点运算符直接访问,也可以通过指针访问,使用箭头运算符(->)。

结构体初始化
    struct Student s1 = {.id = 1,.score = 95.5,.name = "zhangsan"};
    struct Student s2 = {.id = 2,.score = 97,.name = "lisi"};
    struct Student a[] = {{1, 95.5, "zhangsan"},
                          {2, 97,"lisi"},
                          {3, 96,"wanger"}};
结构体对齐

1、结构体按照其最长成员大小对齐,意味着最终的大小必须是最长成员大小的整数倍;

2、结构体成员按照结构体成员声明先后次序依次存放,并且每个成员的首字节放置的位置必须

能够整除成员的字节数;

3、如果结构体某个成员的字节数大于CPU的字节数,则最长按照CPU的字节数对齐;

4、用预处理命令#pragma pack(n) 可以强制编译器按照指定的n来对齐,合法的n的数值分别是1、2、4、8、16。 

结构体传参

 1、用结构体变量的成员作参数。例如,用stu[1].num或stu[2].name作函数实参,将实参值传给

行参。用法和用普通变量作实参是一样的,属于“值传递”方式。应当注意实参与形参的类型保持

一致。

2、用结构体变量作实参。用结构体变量作实参时,采取的也是“值传递”的方式,将结构体变量

所占的内存单元的内容全部顺序传递给形参,形参也必须是同类型的结构体变量。在函数调用期

间形参也要占用内存单元。这种传递方式在空间和时间上开销较大,如果结构体的规模很大时

,开销是很可观的。此外,由于采用值传递方式,如果在执行被调用函数期间改变了形参(也是

结构体变量)的值,该值不能返回主调函数,这往往造成使用上的不便。因此一般较少用这种方法

3、用指向结构体变量(或数组)的指针作实参,将结构体变量(或数组)的地址传给形参。

函数 
struct Student
{
    int id;
    float score;
    char name[20];
};

//遍历
void printStudent(struct Student *s)
{
    printf("%d  %f  %s\n",s->id,s->score,s->name);
}

//数组遍历
void printStudents(struct Student *s,int len)
{
    int i;
    for(i = 0;i < len;++i)
    {
        printStudent(s + i);
    }
}

//交换
void swap(struct Student *s1,struct Student *s2)
{
    struct Student t;
    t = *s1;
    *s1 = *s2;
    *s2 = t;
}

//逆序
void reveser(struct Student *a,int len)
{
    int i;
    for(i = 0;i < len / 2;++i)
    {
        struct Student t;
        t = a[i];
        a[i] = a[len - i - 1];
        a[len - i - 1] = t;
        
        swap(a + i,a + len - i - 1);
    }
}

//快排
int scorecmp(void *p1,void *p2)
{
    struct Student *q1 = (struct Student *)p1;
    struct Student *q2 = (struct Student *)p2;
    if(q1->score > q2->score)
    {
        return 1;
    }
    else if(q1->score < q2->score)
    {
        return -1;
    }
    else
    {
        return 0;
    }
}

//按名字大小排序
int namecmp(const void *p1,const void *p2)
{
    struct Student *q1 = (struct Student *)p1;
    struct Student *q2 = (struct Student *)p2;
    return strcmp(q1->name,q2->name);
}

//按分数大小排序
void sortByScore(struct Student *a,int len)
{
    int i,j;
    for(i = 0;i < len - 1;++i)
    {
        for(j = i + 1;j < len;++j)
        {
            if(a[i].score > a[j].score)
            {
                swap(a + i,a + j);
            }
        }
    }
}


int main()
{
    struct Student s1 = {.id = 1,.score = 95.5,.name = "zhangsan"};
    struct Student s2 = {.id = 2,.score = 97,.name = "lisi"};
    struct Student a[] = {{1, 95.5, "zhangsan"},
                          {2, 97,"lisi"},
                          {3, 96,"wanger"}};
    int len = sizeof(a) / sizeof(a[0]);
    qsort(a,len,sizeof(a[0]),namecmp);
    printStudents(a,len);
    return 0;
}

链表 

 头插算法

struct Node
{
    int data;
    struct Node *next;
};


void push_front(struct Node *pHead,int n)
{
    struct Node *pNew = malloc(sizeof(struct Node));
    pNew->next = pHead->next;
    pHead->next = pNew;
    pNew->data = n;
}

//遍历
void printfList(struct Node *pHead)
{
    struct Node *p = pHead->next;
    while(p != NULL)
    {
        printf("%d\n",p->data);
        p = p->next;
    }
}

//有效个数
void size(struct Node *pHead,int *sum)
{
    struct Node *p = pHead->next;
    while(p != NULL)
    {
        *sum += 1;
        p = p->next;
    }
}

//是否空链表
int isEmpty(struct Node *pHead)
{
    //return size(pHead) == 0;
    return pHead->next == NULL;
}


int main()
{
    struct Node head = {0,NULL};
    push_front(&head,1);
    push_front(&head,2);
    push_front(&head,3);
    push_front(&head,4);
    printfList(&head);
    int sum;
    size(&head,&sum);
    printf("%d\n",sum);
    return 0;
}

  • 15
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值