C语言初阶--结构体

1.结构体声明

1.1结构的基础知识

结构是一些值的集合,这些值称为成员变量。结构的每个成员可以是不同类型的变量。

复杂对象:比如人,书······

人:名字+电话+性别+···

书:书名+作者+定价+···

1.2结构的声明

c 复制代码
struct tag
{
    member-list;
}variable-list;
c 复制代码
//声明的结构体类型struct Peo
struct Peo
{
    //成员变量
    char name[20];
    char tele[12];
    char sex[5]; //男 女 保密,一个汉字占两个字符
    int high;
};

int main()
{
    
    return 0;
}
c 复制代码
//声明的结构体类型struct Peo
struct Peo
{
    //成员变量
    char name[20];
    char tele[12];
    char sex[5]; //男 女 保密,一个汉字占两个字符
    int high;
}p1, p2; //p1和p2是使用struct Peo结构类型创建的2个全局的结构体变量

int main()
{
    
    return 0;
}
c 复制代码
//声明的结构体类型struct Peo
struct Peo
{
    //成员变量
    char name[20];
    char tele[12];
    char sex[5]; //男 女 保密,一个汉字占两个字符
    int high;
};

int main()
{
    struct Peo p1; //结构体变量的创建
    return 0;
}

1.3结构成员的类型

结构的成员可以是标量、数组、指针,甚至是其它结构体。

c 复制代码
struct Peo
{
    char name[20];
    char tele[12];
    char sex[5]; 
    int high;
};
struct Stu
{
    struct Peo p;
    int num;
    float f;
};

1.4结构体变量的定义和初始化

c 复制代码
struct Peo
{
    char name[20];
    char tele[12];
    char sex[5]; 
    int high;
}p1, p2; //p1,p2,p3,p4均为全局结构体变量

struct Peo p3, p4;

int main()
{
    struct Peo p; //p为局部结构体变量
    
    return 0;
}
c 复制代码
struct Peo
{
    char name[20];
    char tele[12];
    char sex[5]; 
    int high;
}p1, p2; //p1,p2,p3,p4均为全局结构体变量

struct Peo p3, p4;

int main()
{
    struct Peo p = {"张三", "17781817031", "男", 190}; //初始化
    
    return 0;
}
c 复制代码
struct Peo
{
    char name[20];
    char tele[12];
    char sex[5]; 
    int high;
}p1, p2; //p1,p2,p3,p4均为全局结构体变量

struct Peo p3, p4;

struct Stu
{
    struct Peo p;
    int num;
    float f;
};

int main()
{
    struct Peo p = {"张三", "17781817031", "男", 190}; //初始化
    struct Stu s = { {"lisi", "199617771699", "女", 158}, 100, 3.14f}; //嵌套结构体的初始化
    
    return 0;
}

调试的监视窗口:

2.结构体成员的访问

c 复制代码
#include <stdio.h>

struct Peo
{
    char name[20];
    char tele[12];
    char sex[5]; 
    int high;
}p1, p2; //p1,p2,p3,p4均为全局结构体变量

struct Peo p3, p4;

struct Stu
{
    struct Peo p;
    int num;
    float f;
};

int main()
{
    struct Peo p = {"张三", "17781817031", "男", 190}; //初始化
    struct Stu s = { {"lisi", "199617771699", "女", 158}, 100, 3.14f}; //嵌套结构体的初始化
    printf("%s %s %s %d\n", p.name, p.tele, p.sex, p.high);
    printf("%s %s %s %d %d %f\n", s.p.name, s.p.tele, s.p.sex, s.p.high, s.num, s.f);
    
    return 0;
}
c 复制代码
#include <stdio.h>

struct Peo
{
    char name[20];
    char tele[12];
    char sex[5]; 
    int high;
}p1, p2; //p1,p2,p3,p4均为全局结构体变量

struct Peo p3, p4;

struct Stu
{
    struct Peo p;
    int num;
    float f;
};

void print2(struct Peo* sp)
{
    printf("%s %s %s %d\n", sp->name, sp->tele, sp->sex, sp->high);
}
int main()
{
    struct Peo p = {"张三", "17781817031", "男", 190}; //初始化
    struct Stu s = { {"lisi", "199617771699", "女", 158}, 100, 3.14f}; //嵌套结构体的初始化
    printf("%s %s %s %d\n", p.name, p.tele, p.sex, p.high);
    printf("%s %s %s %d %d %f\n", s.p.name, s.p.tele, s.p.sex, s.p.high, s.num, s.f);
    
    print2(&p);
    return 0;
}
c 复制代码
#include <stdio.h>

struct Peo
{
    char name[20];
    char tele[12];
    char sex[5]; 
    int high;
}p1, p2; //p1,p2,p3,p4均为全局结构体变量

struct Peo p3, p4;

struct Stu
{
    struct Peo p;
    int num;
    float f;
};

void print2(struct Peo* sp)
{
    printf("%s %s %s %d\n", sp->name, sp->tele, sp->sex, sp->high); //结构体指针->成员变量
}

void print1(struct Peo p)
{
    printf("%s %s %s %d\n", p.name, p.tele, p.sex, p.high); //结构体变量.成员变量
}
int main()
{
    struct Peo p = {"张三", "17781817031", "男", 190}; //初始化
    struct Stu s = { {"lisi", "199617771699", "女", 158}, 100, 3.14f}; //嵌套结构体的初始化
    printf("%s %s %s %d\n", p.name, p.tele, p.sex, p.high);
    printf("%s %s %s %d %d %f\n", s.p.name, s.p.tele, s.p.sex, s.p.high, s.num, s.f);
    
    print1(p);
    print2(&p);
    
    return 0;
}

3.结构体传参

上段代码中,首选print2函数。原因:

函数传参时,参数是需要压栈的。如果传递一个结构体对象时,结构体过大,参数压栈的系统开销比较大,所以会导致性能的下降。

结论:结构体传参时,要传结构体的地址。

作业1:写一个函数,返回参数二进制中1的个数

c 复制代码
//法一
//写一个函数,返回参数二进制中1的个数
#include <stdio.h>

//int count_num_of_1(int n) //负数不适用,修正
//-1
//10000000 00000000 00000000 00000001
//11111111 11111111 11111111 11111110
//11111111 11111111 11111111 11111111
//
int count_num_of_1(unsigned int n)    
{
    int count = 0;
    while (n)
    {
        if ((n % 2) == 1)
        {
            count++;
        }
        n /= 2;
    }
    return count;
}

int main()
{
    int num = 0;
    scanf("%d", &num);
    
    int n = count_num_of_1(num);
    printf("%d\n", n);
    
    return 0;
}
c 复制代码
//法二
//写一个函数,返回参数二进制中1的个数
#include <stdio.h>

int count_num_of_1(int n) 
{
    int count = 0;
    int i = 0;
    for (i = 0; i < 32; i++)
    {
        if (((n >> i) & 1) == 1)
        {
            count++;
        }
    }
    return count;
}

int main()
{
    int num = 0;
    scanf("%d", &num);
    
    int n = count_num_of_1(num);
    printf("%d\n", n);
    
    return 0;
}
c 复制代码
//法三
//写一个函数,返回参数二进制中1的个数
#include <stdio.h>

int count_num_of_1(int n) 
{
    int count = 0;
    while (n)
    {
        n = n & (n - 1);
        count++;
    }
    return count;
}

int main()
{
    int num = 0;
    scanf("%d", &num);
    
    int n = count_num_of_1(num);
    printf("%d\n", n);
    
    return 0;
}

补充 n&(n-1) 的用途

c 复制代码
//如果要判断一个数是不是2的n次方
//2^1 - 2
//10
//2^2 - 4
//100
//2^3 - 8
//1000
if ((n & (n-1)) ==0)
{
    
}

作业2:2个int(32位)整数m和n的二进制表达中,有多少个(bit)位不同?

c 复制代码
//法一
//2个int(32位)整数m和n的二进制表达中,有多少个(bit)位不同?
#include <stdio.h>

int count_diff_bit(int m, int n)
{
    int count = 0;
    int i = 0;
    for (i = 0; i < 32; i++)
    {
        if (((m >> i) & 1) != ((n >> i) & 1))
        {
            count++;
        }
    }
    return count;
}

int main()
{
    int m = 0;
    int n = 0;
    scanf("%d %d", &m, &n);
    int ret = count_diff_bit(m, n);
    printf("%d\n", ret);
    
    return 0;
}
c 复制代码
//法二
//2个int(32位)整数m和n的二进制表达中,有多少个(bit)位不同?
#include <stdio.h>

int count_diff_bit(int m, int n)
{
    int count = 0;
    //^异或操作符:相同为0,相异为1
    int ret = m ^ n;
    //统计ret中二进制位有几个1
    while (ret)
    {
        ret = ret & (ret - 1);
        count++;
    }
    return count;
}

int main()
{
    int m = 0;
    int n = 0;
    scanf("%d %d", &m, &n);
    int ret = count_diff_bit(m, n);
    printf("%d\n", ret);
    
    return 0;
}

作业3:获取一个整数二进制序列中所有的偶数位和奇数位,分别打印出二进制序列

c 复制代码
//获取一个整数二进制序列中所有的偶数位和奇数位,分别打印出二进制序列
int main()
{
    int i = 0;
    int num = 0;
    scanf("%d", &num);
    //获取奇数位的数字
    for (i = 30; i >= 0; i -= 2)
    {
        printf("%d ", (num >> i) & 1);
    }
    printf("\n");
    //获取偶数位的数字
    for (i = 31; i >= 1; i -= 2)
    {
        printf("%d ", (num >> i) & 1);
    }
    
    return 0;
}

作业4:X形图案

c 复制代码
#include <stdio.h>

int main()
{
    int n = 0;
    while (scanf("%d", &n) == 1)
    {
        int i = 0;
        int j = 0;
        for (i = 0; i < n; i++)
        {
            for (j = 0; j < n; j++)
            {
                if (i == j)
                    printf("*");
                else if (i + j == n - 1)
                    printf("*");
                else
                    printf(" ");
            }
            printf("\n");
        }
    }
    return 0;
}

作业5:获取月份天数

c 复制代码
#include <stdio.h>
int is_leap_year(int y)
{
    return (((y%4==0)&&(y%100!=0))||(y%400==0));
}
int main()
{
    int y = 0;
    int m = 0;
    int d = 0;
    int days[13] = {0, 31,28,31,30,31,30,31,31,30,31,30,31};
    //                 1   2  3  ···
    while (scanf(%d%d, &y, &m) == 2)
    {
        int d = days[m];
        if (is_leap_year(y) == 1 && (m == 2))
        {
            d++;
        }
        printf("%d\n", d);
    }
    return 0;
}

0表示假,非0表示真。逻辑操作符&& || !的结果如果是真就是1;如果是假就是0。

作业6:三角形判断

c 复制代码
#include <stdio.h>
int main()
{
    int a = 0;
    int b = 0;
    int c = 0;
    while (scanf("%d %d %d", &a, &b, &c) == 3)
    {
        //判断
        if ((a+b>c) && (b+c>a) && (a+c>b))
        {
            if (a==b && b==c) //等边
            {
                printf("Equilateral triangle!\n");
            }
            else if ((a==b && b!=c) || (a==c && c!=b) || (b==c && c!=a)) //等腰
            {
                printf("Isosceles triangle!\n");
            }
            else //普通
            {
                printf("Ordinary triangle!\n");
            }
        }
        else
        {
            printf("Not a triangle!\n");
        }
    }
    
    return 0;
}

总结

今天就暂且更新至此吧,期待下周再会。如有错误还请不吝赐教。希望对您学习有所帮助,翻页前留下你的支持,以防下次失踪了嗷。

作者更新不易,免费关注别手软。

相关推荐
不二狗28 分钟前
每日算法 -【Swift 算法】实现回文数判断!
开发语言·算法·swift
csdn_aspnet2 小时前
Java 程序求圆弧段的面积(Program to find area of a Circular Segment)
java·开发语言
进击的_鹏3 小时前
【C++】红黑树的实现
开发语言·c++
且撷相思红豆枝3 小时前
一种比较精简的协议
c语言·网络·嵌入式硬件·esp32
无心水3 小时前
【后端高阶面经:MongoDB篇】41、MongoDB 是怎么做到高可用的?
java·开发语言·mongodb·java面试·高可用·后端高阶面经·后端工程师的高阶面经
无心水3 小时前
【后端高阶面经:MongoDB篇】40、怎么优化MongoDB的查询性能?
java·开发语言·mongodb·java面试·后端高阶面经·后端工程师的高阶面经·java高阶面经
信息化未来3 小时前
python 生成复杂表格,自动分页等功能
开发语言·数据结构·python
程序猿阿伟3 小时前
《深入Python:新手易踩的语法雷区与进阶启示》
开发语言·python
gb42152874 小时前
更新时间相差8个小时
java·开发语言
橙子199110164 小时前
说说 Kotlin 中的 Any 与 Java 中的 Object 有何异同?
java·开发语言·kotlin