一、malloc()函数
void* malloc(size_t size);
用于动态分配内存空间。
link = (int*)malloc(size(int)); //申请一段为int大小的内存空间。
int* p = (int*)malloc(sizeof(int))
分配了一个 int
类型大小的内存空间,并将其起始地址赋给指针 p
。
malloc
分配的内存空间是在堆(heap)上。堆是程序运行时动态分配内存的一部分,与栈上的局部变量不同。堆上的内存需要手动管理,当不再需要时,应使用 free
函数释放已分配的内存空间,以避免内存泄漏。
malloc
返回的是 void
指针,这意味着它可以用来分配任何数据类型的内存空间。但是,分配的内存需要根据特定的数据类型进行强制类型转换以进行使用。例如,如果要分配一个整型数组的内存空间,可以使用 int* p = (int*)malloc(sizeof(int) * n)
,其中 n
是数组的大小。
#include <stdio.h>
#include <stdlib.h>int main() {int n;printf("请输入数组大小:");scanf("%d", &n);// 使用 malloc 在堆上分配整型数组的内存空间int* arr = (int*)malloc(sizeof(int) * n);if (arr == NULL) {printf("内存分配失败\n");return 1;}// 给数组赋值for (int i = 0; i < n; i++) {arr[i] = i + 1;}// 输出数组的元素printf("数组的元素为:");for (int i = 0; i < n; i++) {printf("%d ", arr[i]);}printf("\n");// 释放分配的内存空间free(arr);return 0;
}
二、结构体
语法:
struct 结构体类型名
{
数据成员列表;
};
//定义了一个 "数据类型" --- 用户自定义的数据类型
//通常在函数外部声明结构类型,这样就可以被多个函数所使用了
结构体类型可以定义在函数内部,但这样结构体的作用域就只有这个函数内部了。
struct student
{//name char name[20]; //成员变量 各个成员变量之间 用分号隔开//ageunsigned char age;//0~255 -128~127//scorefloat score;//...
}; //注意: 最后这个分号(;) 表示 --- 结构体类型定义完成
struct student s; //s为 自己定义的这种结构体类型的一个变量
访问结构体:
. //结构体成员运算符
结构体变量名.成员变量名
在使用变量名访问时 用 .
在使用指针访问时 用 ->
结构体类型的变量.成员变量名
结构体类型的指针->成员变量名
struct date{
int month;
int day;
int year;
};
struct date today;
//赋值方法一
today.month=07;
today.day=31;
today.year=2014;
//赋值方法二
struct date today={07,31,2014};
//赋值方法三
struct date thismonth={.month=7,.year=2014};
//赋值方法四
today=(struct date){07,31,2014}
//结构体可以 这种赋值操作 thismonth=today,
结构体的定义的形式:
//形式1 先定义类型,后定义变量
struct stu
{
...
};struct stu s;
//形式2 定义类型的同时定义变量
struct stu
{
...
}s1,s2,*s3,s4[10];struct stu s;
//形式3 省略了类型名 --如果只用一次,可以这样写struct
{
...
}s1,s2,*s3,s4[10];
#include <stdio.h>
#include <stdlib.h>
struct student
{char name[20];int sno;float score;
};void inputStuInfo(struct student *p,int len)
{int i = 0;for (i = 0; i < len;++i){printf("name:");scanf("%s",(p+i)->name);printf("sno :");scanf("%d",&(p+i)->sno); //p[i].nameprintf("score:");scanf("%f",&(p+i)->score);}
}void outputStuInfo(struct student *p,int len)
{int i = 0;printf("%10s|%10s|%10s\n","name","sno","score");for (i = 0; i < len;++i){printf("%10s",p->name);printf("%10d",p->sno);printf("%10.2f\n",p->score);p++;}
}void printMenu(void)
{printf("-----Welcome Use Student info System-----\n");printf("1 选择输入的学生人数\n");printf("2 输入信息\n");printf("3 查看学生信息\n");printf("0 退出 \n");printf(">");
}
int main(void)
{int n;int len = 0;struct student *s;while (1){printMenu();scanf("%d",&n);switch(n){case 0:printf("exit----\n");return 0;case 1:printf(">");scanf("%d",&len);s = malloc(len*sizeof(struct student));break;case 2:inputStuInfo(s,len);break;case 3:outputStuInfo(s,len);break;}}return 0;
}
结构体在内存中存储的对齐规则
1.在32位的平台上,默认都是按4字节对齐的。 64位的平台 默认是8字节
2.对于成员变量,
各自在自己的自然边界上对齐。
//整个结构体的对齐
3.如果 成员变量中有比4字节大。
此时 整个结构体按照4字节对齐。 //32位的平台
4.如果 成员变量中没有有比4字节大。
此时 整个结构体按照最大的那个成员对齐。
自然边界对齐
int -- 4字节 --- 能被4整除的地址编号上
short -- 2字节 --- 能被2整除的地址编号上
char -- 1字节 --- 能被1整除的地址编号上
三、共用体union(联合体)
union 共用体名
{
成员列表; //各个变量
}; //表示定义一个共用体类型
1.共用体
初始化 --- 只能给一个值,默认是给到第一个成员变量的共同体中属性赋值会损坏其他属性的值。
2.共用体成员变量辅助
共用体用的数据最终存储的 --- 应该是最后一次给到的值。
但是只能影响到 自己数据类型对应的空间中的数据
3.可以判断大小端
4.实际用途
a.节省空间
b.进行数据转换
192.168.1.169 //ip本质是个 32位的数值
5.共用体的大小 --是成员变量中最大的那个成员的大小共用体大小计算,不一定就等于最大成员;
6.共用体类型可以是函数参数,也可以是函数返回值类型
union{char a[3];char b;
} A ; // sizeof(A) = 3union{char a[3];short b;
} B ; // sizeof(B) = 4union{char a[5];int b;
} C ; // sizeof(C) = 8
和结构体对齐规则一样。
int isEndian(void)
{union demo{int a;char b;}d;d.a = 1;return d.b;
}
返回1 小端存储, 返回0 大端存储。
四、枚举 enum
枚举:一枚一枚的列举
如果一个变量只有几种可能的值,则可以定义为枚举类型。
所谓“枚举”是指将变量的值一一列举出来,
变量的值只限于列举出来的值的范围内。
注意:
1.枚举 提高了代码可读性
2.枚举 本质上是int类型
枚举 与 整型 类型兼容
3.不足
因为枚举类型 --- 本质上是个整型类型,
所以枚举类型的变量的值,并不能真正限定在指定的哪些值范围中
4.枚举类型
可以做函数 形参 和 返回值
定义数组也可以,本质上就是整型数据
enum DAY
{
MON=1, TUE, WED, THU, FRI, SAT, SUN
};注意:第一个枚举成员的默认值为整型的 0,后续枚举成员的值在前一个成员上加 1。我们在这个实例中把第一个枚举成员的值定义为 1,第二个就为 2,以此类推。
enum season {spring, summer=3, autumn, winter};
没有指定值的枚举元素,其值为前一元素加 1。也就说 spring 的值为 0,summer 的值为 3,autumn 的值为 4,winter 的值为 5。
union MyUnion {int i;float f;char c;
};
union MyUnion u;u.i = 42; // 将整数 42 存储在共用体中
printf("%d\n", u.i); // 输出 42u.f = 3.14; // 将浮点数 3.14 存储在共用体中
printf("%f\n", u.f); // 输出 3.14u.c = 'A'; // 将字符 'A' 存储在共用体中
printf("%c\n", u.c); // 输出 'A'
#include <stdio.h>
#include <stdlib.h>
int main()
{enum color { red=1, green, blue };enum color favorite_color;/* ask user to choose color */printf("请输入你喜欢的颜色: (1. red, 2. green, 3. blue): ");scanf("%d", &favorite_color);/* 输出结果 */switch (favorite_color){case red:printf("你喜欢的颜色是红色");break;case green:printf("你喜欢的颜色是绿色");break;case blue:printf("你喜欢的颜色是蓝色");break;default:printf("你没有选择你喜欢的颜色");}return 0;
}
请输入你喜欢的颜色: (1. red, 2. green, 3. blue): 1
你喜欢的颜色是红色