【C 语言】结构体相关 的 函数 指针 数组(一)

结构体概述 : 结构体是 多个 变量的集合, 变量的类型可以不同;


-- 可进行的操作 : 结构体可以进行 拷贝 赋值操作, 可以作为 函数参数 和 函数返回值;




1. 结构体的基本使用



结构体声明 : struct 结构标记 {结构成员} 普通变量;


-- 结构体示例 :



struct student
    {
  char *name;
  int age;
    };


-- 结构标记 : struct 后面的 student 是结构标记, 这个标记 可写 可不写, 其作用是 为结构命名, 结构标记可以代表 {} 中的声明的所有的成员变量;

-- 结构成员 : 在 {} 中定义的变量就是结构成员;


-- 普通变量 : 在声明结构体的时候后面可以加上若干普通变量, 相当于定义结构体变量;






结构体变量声明 : 可以在定义的时候声明变量, 也可以在定义完结构体使用 结构标记 声明变量;


-- 定义结构体时声明变量 : 这种声明变量的方式可以不用 结构标记, 变量名写在 花括号 后面, 用头号隔开;



struct student
    {
  char *name;
  int age;
    } s1, s2, s3;


-- 使用结构标记声明 : 结构标记 student 代表了花括号的声明, 是 结构体的简写, 可以使用结构标记代替花括号中的内容;


struct student s4, s5, s6;





结构体内存分配 : 结构体内存是在声明变量的时候分配的, 如果只声明了结构体, 没有声明对应变量, 那么不会分配内存;






结构体变量初始化 :


-- 声明结构体的时候初始化 : struct student s1 = {"Tom", 12} ; 注意 初值表中必须时结构体对应类型的常量表达式;


-- 声明之后初始化 : 结构体变量名.成员名 可以访问结构体中的成员变量, s1.name = "Tom"; s2.age = 12;




结构体嵌套 : 结构体中的成员变量可以是 结构体变量;



struct student
    {
  char *name;
  int age;
    } s1;
    struct class
    {
  struct student s1;
  struct student s2;
    } c1;


结构体代码示例 :



/*************************************************************************
    > File Name: base_struct.c
    > Author: octopus
    > Mail: octopus_work.163.com 
    > Created Time: 2014年03月24日 星期一 10时49分46秒
 ************************************************************************/
#include<stdio.h>
int main(int argc, char **argv)
{
    /*
  * 声明结构体 同时声明变量s1
  */
    struct student
    {
  char *name;
  int age;
    } s1;
    /*
  * 结构体嵌套
  */
    struct class
    {
  struct student s1;
  struct student s2;
    } c1;
    struct student s2 = {"Tom", 12};/*只有声明的时候才能对结构体初始化才能使用花括号赋值*/
    struct class c2 = {{"Jack", 13}, {"Pig", 15}};
    s1.name = "Hack";  /*变量声明后对结构体赋值只能一个一个赋值*/
    s1.age = 14;
    //s1 = {"fuck", 1};  /*只有在初始化的时候才能使用 花括号初始化结构体变量*/
    c1.s1.name = "CJ";
    c1.s1.age = 21;
    c1.s2.name = "KW";
    c1.s2.age = 22;
    /*访问结构体中的变量, 使用 . 进行访问*/
    printf("s1 : name = %s, age = %d \n", s1.name, s1.age);
    printf("s2 : name = %s, age = %d \n", s2.name, s2.age);
    printf("c1 : s1 : name = %s, age = %d ; s2 : name = %s, age = %d \n", c1.s1.name, c1.s1.age, c1.s1.name, c1.s2.age);
    printf("c2 : s1 : name = %s, age = %d ; s2 : name = %s, age = %d \n", c2.s1.name, c2.s1.age, c2.s1.name, c2.s2.age);
    return 0;
}



执行结果 :


octopus@octopus-Vostro-270s:~/code/c/struct$ gcc base_struct.c 
octopus@octopus-Vostro-270s:~/code/c/struct$ ./a.out 
s1 : name = Hack, age = 14 
s2 : name = Tom, age = 12 
c1 : s1 : name = CJ, age = 21 ; s2 : name = CJ, age = 22 
c2 : s1 : name = Jack, age = 13 ; s2 : name = Jack, age = 15



2. 结构体与函数





结构体的合法操作 :


-- 整体复制 : 结构体可以复制;


-- 整体赋值 : 声明结构体的时候可以整体赋值, 在其它情况下不可以;


-- & 取地址 : 使用 & 运算符获取 结构体地址;


-- 访问成员 : 使用 结构体变量名.成员变量名 可以访问成员变量;




函数传递结构体方法 :


-- 传递结构体成员 : 将结构体拆开, 将其中的成员变量分别传入;



struct class create_class(struct student s2, struct student s3)
{
    struct class c1 = {s2, s3};
    return c1;
}

-- 传递结构体 :  将整个结构体当做参数传入, 这种情况和传递其它类型参数一样, 都是通过值传递的;



struct class create_class(struct student s2, struct student s3)
{
    struct class c1 = {s2, s3};
    return c1;
}

-- 传递结构体指针 : 传递结构体的指针, 访问形式如下;



/*
 * 传入一个结构体指针
 * 通过指针访问结构体的方法 : 
 *   (*结构体指针变量).成员变量 访问;
 *   结构体指针变量 -> 成员变量 访问;
 */
void printf_struct_pointer(struct student *s)
{
    printf("student : (*s).name = %s, (*s).age = %d \n", (*s).name, (*s).age);
    printf("student : s->name = %s, s->age = %d \n", s->name, s->age);
}


结构体指针访问 :


-- 示例 : 定义一个结构体指针;



struct student
    {
  char *name;
  int age;
    }*p;
-- "." 和 "->"优先级 : 这两个运算符都是从左到右运算, 都是右结合; "." 和 "->" 优先级比 "*" , "++" 优先级要高; 这两个运算符 与 () [] 是四个优先级最高的运算符;
-- ++p->age 分析 : 是对结构体中的 age 进行自增操作;
-- *p->name 分析 : 获取 结构体中的 name 字符串的值(注意不是指针|地址);
-- *p++->name 分析 : 先获取 name 字符串的值, 再将p自增;






结构体函数示例 :


/*************************************************************************
    > File Name: method_struct.c
    > Author: octopus
    > Mail: octopus_work.163.com 
    > Created Time: 2014年03月24日 星期一 14时46分16秒
 ************************************************************************/
#include<stdio.h>
/*声明一个结构体类型, 其成员变量是普通变量*/
struct student
{
    char *name;
    int age;
};
/*声明一个结构体类型, 其成员变量是结构体*/
struct class
{
    struct student s1;
    struct student s2;
};
/*
 * 传递 2 个结构体的成员变量
 * 在函数中创建结构体并返回
 */
struct student create_student(char *name, int age)
{
    struct student s1 = {name, age};
    return s1;
}
/*
 * 传递 2 个结构体变量
 */
struct class create_class(struct student s2, struct student s3)
{
    struct class c1 = {s2, s3};
    return c1;
}
/*
 * 传入一个结构体指针
 * 通过指针访问结构体的方法 : 
 *   (*结构体指针变量).成员变量 访问;
 *   结构体指针变量 -> 成员变量 访问;
 */
void printf_struct_pointer(struct student *s)
{
    printf("student : (*s).name = %s, (*s).age = %d \n", (*s).name, (*s).age);
    printf("student : s->name = %s, s->age = %d \n", s->name, s->age);
}
int main(int argc, char **argv)
{
    /*使用函数获取一个结构体, 传入结构体的值*/
    struct student s1 = create_student("Tom", 11);
    printf("student : name = %s, age = %d \n", s1.name, s1.age);
    /*创建一个成员变量是结构体的结构体, 并打印结构体数据*/
    struct class c1 = create_class(create_student("Jack", 12), create_student("CJ", 13));
    printf("c1 : s1 : name = %s, age = %d ; s2 : name = %s, age = %d \n", c1.s1.name, c1.s1.age, c1.s2.name, c1.s2.age);
    /*声明结构体指针*/
    struct student *p = &s1;
    printf_struct_pointer(p);
    return 0;
}


执行结果 :


octopus@octopus-Vostro-270s:~/code/c/struct$ gcc method_struct.c 
octopus@octopus-Vostro-270s:~/code/c/struct$ ./a.out 
student : name = Tom, age = 11 
c1 : s1 : name = Jack, age = 12 ; s2 : name = CJ, age = 13 
student : (*s).name = Tom, (*s).age = 11 
student : s->name = Tom, s->age = 11
上一篇:【C 语言】结构体相关 的 函数 指针 数组(二)


下一篇:【嵌入式开发】C语言 命令行参数 函数指针 gdb调试(一)