结构体初识

来源:互联网 发布:初中编程学哪个 编辑:程序博客网 时间:2024/06/06 00:45

结构体初识

复习
* 指针:
* 指针就是内存中的物理编号,地址

    int num = 10;    int *p_num = #
  • 指针数组元素的指针

    • 一个指针,存储了数组元素的地址
      int nums[] = {1,2,3,4,5,};int *p_num = &nums[2];// 数组中的元素在内存中是连续的p_num++;//p_num的值 + sizeof(数据类型)//加完之后 p_num指向下一个元素p_num--;//p_num的值 - size(数据类型)// 减完之后。p_num指向了上一个元素// 正因为有这个特性// 四中遍历数组的方式int nums[] = {1,2,3,4,5};sizeof(nums) / sizeof(int);int *p_num =  nums;// nums[0]for(int i = 0; i < len; i++){*(p_num + i)*(p_num++)*(nums + i)nums[i]}
  • 字符串的两种存储方式
    • char name[] = {“jack”}
    • char *p_name = “jack”;
  • 字符串数组
    • char *p_name[5] = {“”,”“,”“,”“};

使用fputs 函数将字符串输出到指定的流

  • fputs() 函数
    • 作用:将数据输出到指定的流中
    • 流:
      • 标准输出流: 控制台
      • 文件流 硬盘上的文件
      • 使用格式:
      • char *name = “abcdef”;
      • fputs(要输出的字符串,指定的流);
  • 将字符串数据输出到标准输出流
    • fputs(需要输出的字符串,stdout);
  • 字符串存储到文件中

    "写一个字符串到文件File* fp = fopen("文件的路径",打开文件的模式);//相当于 定义了一个文件指针,这个文件指针指向了 一个文件char * name = "我爱好者能够过";fputs(name,fp);//就是name存储的字符串 写到 fp指向文件里了fclose(fp);
    注意:打开文件的模式,"w","r","a" append,表示追加当操作文件模式 是"w"的时候,如果文件不存在,那么 创建一个

    如果文件存在,那么 覆盖原来内容,全部清空原来的内容
    当操作文件模式 是”a”的时候,如果文件不存在,那么 创建一个
    如果存存在,那么往后写

fgets()函数: 接收字符串
* 使用语法:
* fgets(要将字符串存储到哪一个数组中,最多接收多少长度,指定的流)
* 第二个参数: 我们写一个n 那么最多接收的就是n-1个长度
* 特点 安全
* 输入字符串的长度 >= 只会接收 n-1 个字符,并且末尾自动加上‘\0’;
* 输入的字符串的长度 == n-1 最好
* 输入的字符串 < n-1 不仅会吧输入的字符串放进去 还会把’\n’一并接收
* 如果出现第c种情况,解决方案
找到’\n’的位置 把’\n’换成’\0’即可
只要计算字符串的长度就可以找到’\n’,
int len = strlen(字符数组名);
‘\n’所在的位置 就是 len-1下标

代码如下:    char input[5];    printf("请输入:\n");    fgets(input, 5, stdin);    size_t len = strlen(input);    if(input[len - 1] == '\n')    {        input[len-1] = '\0';    }    printf("你输入的是:%s\n",input);

fgets()函数

```

1.使用fgets函数从文件流中读取数据的步骤?
把刚刚装进冰箱的大象拿出来
1>开门
2>拿出来
3>关门

//1. 创建1个读取文件的文件流.FILE* fp = fopen("/Users/Itcast/Desktop/abc.txt", "r");//2.准备1个字符数组.准备存储读取到的字符串数据.char content[50];//3.使用fgets函数从指定的文件流中读取.fgets(content, 50, fp);//4. 读取成功.printf("读取的内容是: %s\n",content);]//5. 关闭文件流.fclose(fp);    ```
  • const 修饰普通变量
    *使变量的值不能改变
  • const 修饰数组
    • const int arr[4] = {12,33,44}
    • 数组的元素的值是无法更改的
  • * 被const修饰的变量只能读不能改*
  • const 修饰指针
    • int num = 10;
    • const int *p1 = #
      • 无法通过p1指针去修改指针指向的变量的值,但是直接操作变量是可以的
      • 但是指针变量的值可以该 可以让怕p1指针指向另外一个变量
    • int *const p1 = #
      • p1 的值不能修改但是可以通过p1去修改p1 指向变量的值
    • int const *const p1 = #
      • 什么都不能修改
  • 使用场景:

    • 当某些数据是固定的,在整个程序运行期间都不会发生变化. 并且你也不允许别人去修改.
      那么这个时候,我们就可以使用const修饰.

    • 当函数的参数是1个指针的时候,为了防止函数的内部修改实参变量的值.
      那么这个时候,我们就可以使用const修饰

malloc函数

  • 堆中申请的字节空间的特点
    • 如果空间申请完后 不释放 会一直在程序中 直到程序结束
  • 所以在对中申请字节空间的步骤
    • 申请>>>使用>>>释放
  • 如何在堆区中申请置顶字节数的空间呢
    #include <stdlib.h>    malloc(),calloc(),realloc();
  • malloc 函数的使用
    • 作用 向对空间申请 置顶的字节空间
    • 格式: malloc(字节数)
    • 返回 void* 通用指针
    • int *p = malloc(4 x sizeof(int) );
  • 注意的问题
    • 在堆区申请的字节空间是从 低地址到 高地址 连续的空间
    • 在堆区申请的字节,里面是有值得,值是垃圾值,不会走动清零
    • 在堆区申请的字节空间的时候有可能会失败 如果失败则返回NULL
    • 所以最好进行判断 if(指针 != NULL){操作}
    • 申请的空间用完之后一定要释放
      • free(申请空间的第一个字节地址);

calloc函数的使用
* 作用: 向堆空间申请置顶的字节数的空间
* 格式: calloc(块数,每一个块数的字节);
* int *p_num = calloc(10,sizeof(int));
* 优点: 申请的字节空间数据会全部清零

realloc函数
* 作用: 如果已经的空间不够用,可以进行扩容
* 格式: realloc(原来字节空间的指针,扩容后的容量)
* 注意:
* 如果原来的空间 后面还有剩余的空间,并且足够扩容,那么直接扩容在尾部
* 如果原来的空间 后面还要剩余空间但是不够扩容,会重新找一个足够的空间,会把原来的空间中的数据全部转移过去,而且原来的空间会自动释放

指针与函数

  • 指针作为函数的参数
    • 优点
      • 在函数内部想改 变量的值 ,同时也改变主函数中的参数: 地址传递
      • 当一个函数需要返回多个值
  • 指针作为函数的返回值
    • 函数可以返回局部变量,但是不能返回局部变量的地址
    • int num = returnInt();
    • 如果一定要申请一个变量地址,只能在堆中申请

指向函数的指针

1.如何声明一个指向函数的指针
返回值类型 (*指针名)([参数列表]);

2.指向函数的指针的初始化
因为函数名就是这个函数的地址
所以直接将符合条件的函数的名称赋值给这个指针.

3.有了函数的指针之后,如何使用这个函数的指针
void (*pFunc)() = test;//pFunc这个函数的指针 指向了test这个函数
pFunc(); (*pFunc)();

4.定义一个指针,指向一个函数的小技巧
直接拷贝函数的头部,去掉函数名
变为一个小括号,在小括号里写上一个* 然后跟上指针名字

结构体

  • 如何使用结构体来创建新的数据类型
    • 格式: 就以Student 信息的结构体为例
      “`
      struct Student
      {
      char name[20];
      int age;
      char sex;
      float score;
      int *p_num;
      }
      //这里只是顶一个新的类型 不会占用内存空间
* 声明结构体类型的变量    * 语法格式:    *  struct Student stu;* 注意: 这个时候结构体的变量类型是   struct Student,类型而不是  Student 类型**结构体的初始化*** 初始化语法

// 结构体变量名称.成员变量名 = 数据;
struct Car{
char * logo;
char * xinghao;
double price;
int seatCount;
char * color;
};

struct Car bmw_520;bmw_520.logo = "宝马";bmw_520.xinghao = "520";bmw_520.price = 50.6;bmw_520.seatCount = 6;bmw_520.color = "白色";printf("我有一辆%s车,他的型号是%s,价值%.2lf万\n",bmw_5    20.logo,bmw_520.xinghao,bmw_520.p
**使用结构体注意*** 要先定义结构体类型, 才可以根据这个类型声明变量* 结构体变量也是一个变量  也可以批量声明    *  struct Car car1,car2;* 定义结构体名称的规范    **首字母一定要大写*** 在声明结构体类型的同时,可以定义结构体变量         struct Car{        char * logo;        char * xinghao;        double price;        int seatCount;        char * color;           } bmw1,bmw2;           struct Car bmw3,bmw4;* 匿名结构体:没有名字的结构体类型    struct    {        char * logo;        char * xinghao;        double price;        int seatCount;        char * color;         }bmw5,bmw6;         //strcut bmw7;         注意:匿名结构体类型 只能在定义类型的同时         定义结构体变量**结构体变量的默认值和初始化*** 另外一种比较常见的初始化方式

struct Car
{
char * logo;
char * xinghao;
double price;
int seatCount;
char * color;
};

struct Car bmw1 = {"宝马","520",20.8,6,"白色"};

“`
* 结构体变量赋值的时候
* 如果不给赋值,那么结构体变量中的每一个成员都是垃圾值
* 如果你通过 ‘.’ 这种语法给结构体变量中的某个成员赋值 那么没有赋值的默认值就是 ‘0’;
* 注意:
* 赋值的时候大括号中的数据的顺序 类型 个数 要和类型定义的时候完全一致

* 结构体的作用域*

  • 结构体的作用域分为两种
    • 全局结构体: 定义在函数之外的机构提类型
    • 局部结构体: 定义在函数内部的结构体
    • 一般情况下 我们的结构体类型都是定义在函数的外面,文件的做上面,以让所有的函数都可以使用
      * 结构体变量之间的互相赋值*
  • 相同结构类型的变量之间绝对是可以赋值的
    因为他们的类型相同
  • 结构体变量之间的赋值原理
    将原结构体变量中的灭一个成员的值 拷贝一份
    赋值给目标结构体变量中对相应的成员
  • 结构体变量之间的赋值是值传递

    假设有一个函数,这个函数的参数是一个结构体在函数内部修改结构体变量中的摸一个元素,是不会影响主调函数的中是实参的
0 0
原创粉丝点击