c语言中的结构体

1.结构体是什么

在C编程中,结构体是单个名称下的变量(可以是不同类型)的集合。

1.1定义结构体

struct structureName 
{
    dataType member1;
    dataType member2;
    ...
};

代码示例:

struct Person
{
    char name[50];
    int citNo;
    float salary;
};

1.2创建结构体

struct Person
{
    char name[50];
    int citNo;
    float salary;
};

int main()
{
    struct Person person1, person2, p[20];
    return 0;
}

也可以这样创建

struct Person
{
    char name[50];
    int citNo;
    float salary;
} person1, person2, p[20];

1.3 访问结构体的属性

你可以使用两种操作符来访问结构体的属性:

  • . member operator
  • -> Structure pointer operator

代码示例:

//结构体属性的访问
#include<stdio.h>

struct Person {
    char name[50];
    int citNo;
    float salary;
};

int main(void) {
    //首先使用结构体语法定义一个person变量,以及一个指向person变量的指针
    struct Person *personPtr, person;
    //指针指向person1变量
    personPtr = &person;
    
    
    printf("Enter name: ");
    scanf("%s", &personPtr->name);
    
    printf("Enter citNo: ");
    scanf("%d", &personPtr->citNo);
    
    printf("Enter salary: ");
    scanf("%f", &personPtr->salary);
    
    //1.使用指针访问属性
    //1.1使用->操作符
    printf("%s\n",personPtr->name);
    printf("%d\n",personPtr->citNo);
    printf("%f\n",personPtr->salary);

    //1.2使用.操作符
    printf("%s\n",(*personPtr).name);
    printf("%d\n",(*personPtr).citNo);
    printf("%f\n",(*personPtr).salary);

    //2.使用变量访问属性
    printf("%s\n",person.name);
    printf("%d\n",person.citNo);
    printf("%f\n",person.salary);
    
}

注意:这里使用变量访问属性的时候,并没有使用->操作符,因为变量(这里就是默认值结构体变量)不支持该操作符,可以参考如下图片:

Snipaste_2019-10-29_20-40-57.png

Output

Enter name: eric
Enter citNo: 1
Enter salary: 1.1
eric
1
1.100000
eric
1
1.100000
eric
1
1.100000

2.typedef关键字

这个关键字可以用来给结构体起别名。

下列代码

struct Distance{
    int feet;
    float inch;
};

int main() {
    struct Distance d1, d2;
}

和以下代码效果一致

typedef struct Distance{
    int feet;
    float inch;
} distances;

int main() {
    distances d1, d2;
}

3.结构体嵌套

你可以在一个结构体里面定义子结构体属性,代码示例如下:

struct complex
{
 int imag;
 float real;
};

struct number
{
   struct complex comp;
   int integers;
} num1, num2;

//这样来访问子结构体的属性
num2.comp.imag = 11;

4.结构体中的动态内存分配

在继续阅读之前,可以先参考之前的一篇文章C语言动态内存分配

代码示例:

#include <stdio.h>
#include <stdlib.h>
struct person {
   int age;
   float weight;
   char name[30];
};
int main()
{
   struct person *ptr;
   int i, n;
   printf("Enter the number of persons: ");
   scanf("%d", &n);
   // allocating memory for n numbers of struct person
   ptr = (struct person*) malloc(n * sizeof(struct person));
   for(i = 0; i < n; ++i)
   {
       printf("Enter first name and age respectively: ");
       scanf("%s %d", &(ptr+i)->name, &(ptr+i)->age);
   }
   printf("Displaying Information:\n");
   for(i = 0; i < n; ++i)
       printf("Name: %s\tAge: %d\n", (ptr+i)->name, (ptr+i)->age);
   return 0;
}

Output

Enter the number of persons: 3
Enter first name and age respectively: ericling 22
Enter first name and age respectively: bob 23
Enter first name and age respectively: lucy 24
Displaying Information:
Name: ericling  Age: 22
Name: bob       Age: 23
Name: lucy      Age: 24

5.结构体变量传参和返参

5.1使用结构体变量来传递参数

代码示例:

#include <stdio.h>
struct student
{
    char name[50];
    int age;
};
// function prototype
void display(struct student s);
int main()
{
    struct student s1;
    printf("Enter name: ");
    scanf("%[^\n]%*c", s1.name);
    printf("Enter age: ");
    scanf("%d", &s1.age);
    
    display(s1);   // passing struct as an argument
    
    return 0;
}
void display(struct student s) 
{
  printf("\nDisplaying information\n");
  printf("Name: %s", s.name);
  printf("\nAge: %d", s.age);
}

Output

Enter name: eric
Enter age: 23

Displaying information
Name: eric
Age: 23

5.2函数返参结构体变量

代码示例

//函数返回结构体变量 
#include <stdio.h>
struct student
{
    char name[50];
    int age;
};
// function prototype
struct student getInformation();
int main()
{
    struct student s;
    s = getInformation();
    printf("\nDisplaying information\n");
    printf("Name: %s", s.name);
    printf("\nRoll: %d", s.age);
    
    return 0;
}
struct student getInformation() 
{
  struct student s1;
  printf("Enter name: ");
  scanf ("%[^\n]%*c", s1.name);
  printf("Enter age: ");
  scanf("%d", &s1.age);
  
  return s1;
}   

Output:

Enter name: eric
Enter age: 23

Displaying information
Name: eric
Roll: 23

5.3结构体变量参数的引用传递

代码示例:

#include <stdio.h>
typedef struct Complex
{
    float real;
    float imag;
} complex;
void addNumbers(complex c1, complex c2, complex *result); 
int main()
{
    complex c1, c2, result;
    printf("For first number,\n");
    printf("Enter real part: ");
    scanf("%f", &c1.real);
    printf("Enter imaginary part: ");
    scanf("%f", &c1.imag);
    
    printf("For second number, \n");
    printf("Enter real part: ");
    scanf("%f", &c2.real);
    printf("Enter imaginary part: ");
    scanf("%f", &c2.imag);
    
    //值传递测试,c1和c2都是属于值传递,result传递的是地址
    addNumbers(c1, c2, &result); 
    printf("\nresult.real = %.1f\n", result.real);
    printf("result.imag = %.1f", result.imag);
    
    //打印值传递的两个结构体的属性,查看是否被修改
    printf("\nc1.real = %.1f", c1.real);
    printf("\nc2.real = %.1f\n", c2.real);
    
    return 0;
}
void addNumbers(complex c1, complex c2, complex *result) 
{
     result->real = c1.real + c2.real;
     result->imag = c1.imag + c2.imag; 
     c1.real = 1.1111;
     c2.real = 2.2222;
}

Output:

For first number,
Enter real part: 3
Enter imaginary part: 1.3
For second number,
Enter real part: 4
Enter imaginary part: 1.4

result.real = 7.0
result.imag = 2.7
c1.real = 3.0
c2.real = 4.0

可以看到,引用传递的result的两个属性都已经修改了,而值传递的c1,c2的real属性还是用户输入的数据。

6.union关键字

union关键字的用法和struct关键字非常像,代码示例如下:

6.1定义union

union car
{
  char name[50];
  int price;
};

6.2创建union

union car
{
  char name[50];
  int price;
};
int main()
{
  union car car1, car2, *car3;
  return 0;
}

或者这样

union car
{
  char name[50];
  int price;
} car1, car2, *car3;
 

6.3访问属性

struct一致,使用.操作符来访问变量属性,使用->操作符来访问指针属性。

6.4unionstruct的不同

看来看去,好像union和struct并没有什么不同,看一下下面的代码

#include <stdio.h>
union unionJob
{
   //defining a union
   char name[32];
   float salary;
   int workerNo;
} uJob;

struct structJob
{
   char name[32];
   float salary;
   int workerNo;
} sJob;

int main()
{
   printf("size of union = %d bytes", sizeof(uJob));
   printf("\nsize of structure = %d bytes", sizeof(sJob));
   return 0;
}

Output

size of union = 32
size of structure = 40

sJob可以这样累加

  • the size of name[32] is 32 bytes
  • the size of salary is 4 bytes
  • the size of workerNo is 4 bytes

那为什么uJob 是32 bytes?

因为它获取的是最大的一个元素的bytes,在这里也就是32

最关键的原因是什么?

You can only access a single member of a union at one time.

你一次只可以访问一个union属性,不理解的话,可以看一下下面的这段代码

#include <stdio.h>
union Job
{
   float salary;
   int workerNo;
} j;
int main()
{
   j.salary = 12.3;
   j.workerNo = 100;
   printf("Salary = %.1f\n", j.salary);
   printf("Number of workers = %d", j.workerNo);
   return 0;
}

Output

Salary = 0.0
Number of workers = 100

12.3不见了!这是因为,后面访问workerNo属性时,因为一次只能访问一个属性,所以就可以理解为被覆盖。你可以试试把两个赋值语句调换顺序,看结果怎么样。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值