数据结构(一) (2)

指针变量的运算: 
  指针变量不能相加、相乘、相除
  如果两指针变量属于同一数组,则可以相减
  指针变量可以加减一个整数,前提是最终结果不能超过指针最大可访问范围
     

// 指针变量的运算 p + i 的值是 p + i*(所指向的变量所占字节数) p - i 的值是 p - i*(所指向的变量所占字节数) p++ 等价于 p + 1 p-- 等价于 p - 1 // 下面是一个通过函数修改数组内部元素 void my_Array(int *a , int length) { for(int i = 0; i < length; i++) { *a[i]++; // 给每个元素加 1 } } int main(void){ int a[5] = {1,2,3,4,5}; my_Array(a , 5); // 调用 }

结构体

为什么会出现结构体

为了表示一些复杂的数据,而普通的基本数据无法满足要求.

什么叫结构体
结构体是用户根据实际需要,自己定义的复合数据类型

// 如学生类型 struct Student{ int age; char * name; // name 不同,赋值方法不同 char name2[100]; // 这个只能 strcpy(s.name2, "zhangwangdsd"); 字符串拷贝 double height; };

如何使用结构体

总结起来有两种结构体的使用方式:直接使用 && 通过指针使用
struct Student ss = {12,"xiaoyou",1.73,"xiaozhang"};
struct Student *pst = &ss;

ss.name ; 这里直接操作结构体本身
pst -> name ; 这里通过指针地址操作,更加节省空间

struct Student{ // 自定义结构体 int age; char * name; double height; char name2[100]; }; int main(void) { struct Student s = {12,"xiaoyou",1.73,"xiaozhang"}; // 直接使用 printf(" age = %d \n name = %s \n height = %.2f \n",s.age,s.name,s.height); s.age = 21; s.name = "xiaozhu"; strcpy(s.name2, "zhangwangdsd"); // 字符串拷贝 s.height = 1.70; printf(" age = %d \n name = %s \n height = %.2f \n %s \n",s.age,s.name,s.height,s.name2); // 以指针的方式使用 struct Student *pst = &ss; pst -> name = "my new name"; printf(" name = %s\n",pst->name); printf(" name = %s\n",(*pst)->name); // pst -> name 等价于 (*pst).name , // 而(*pst).name 又等价于 ss.name // 所以 pst -> name 等价于 ss.name return 0; }

注意事项
结构体变量的类型为: struct Student
结构体变量不能加减乘除,但是能够相互赋值
普通结构体变量和结构体指针变量作为函数传参的问题

typedef struct Student{ // 结构体定义 int age; char * name; char name2[100]; double height; }myStudent; // 直接传递整个结构体数据,耗时 && 浪费内存空间 void func(struct Student st); // 直接传递 只占用 4 byte 的指针,省时效率也高 <推荐用法> void func2(struct Student * pst); int main(void){ myStudent ss = {12,"xiaoyou",1.73}; func(ss); func2(&ss); return 0; } void func(struct Student st){ printf("age = %d \n name = %s",st.age,st.name); } void func2(struct Student * pst){ printf("age = %d \n name = %s",(*pst).age,(*pst).name); printf("age = %d \n name = %s",pst->age,pst->name); } 动态内存分配和释放

平时直接创建数组的写法都是静态创建,创建完毕之后在整个程序的运行过程中,会固定占用对应的内存,不仅会造成内存空间浪费,还无法动态添加元素,所以局限性很大,而程序中我们为了避免这种情况,应该使用动态的方式创建和销毁数组。

// 静态创建数组 int a[5] = {1,2,3,4,5};

动态构造一维数组

动态构造一个 int 型的一维数组。

int *p = (int *)malloc(int length); 1. void * malloc(size_t __size) 函数,只有一个 int 类型的形参,表示要求系统分配的字节数 2. malloc 函数的功能是请求系统 length 个字节的内存空间,如果请求完成则返回的是第一个字节的地址, 如果请求不成功,则返回NULL 3. malloc 函数能且只能返回第一个字节的地址,所以我们需要把没有实际意义的第一个字节地址(干地址)转化为一个有实际意义的地址, 所以 malloc 前面必须加(数据类型 *),表示把这个无意义的地址转化为对应类型的地址 实例: int *p = (int *)malloc(50); 表示将系统分配的 50 个字节的第一个字节的地址转化为 int 类型的地址,准确的说是转化为 4 个一组的地址的首地址, 这样 p 就指向了第一个四个字节··· p+i 就指向了第 i+1 个四个字节,p[0],p[i]也就分别是第一个,第i+1个元素。 double *p = (double *)malloc(80); 表示将系统分配的 80 个字节的第一个字节的地址转化为 double 类型的地址,准确的说是转化为 8 个一组的地址的首地址, 这样 p 就指向了第一个八个字节··· p+i 就指向了第 i+1 个八个字节,p[0],p[i]也就分别是第一个,第i+1个元素。 4. free(p); 释放 p 所指向的内存,而不是释放 p 本身所占用的内存

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zywgxd.html