3.预备知识【郝斌数据结构】
预备知识
1.指针
1) 指针的重要性:指针是C语言的灵魂
2)定义
地址:内存单元的编号,从0开始非负整数。范围:0-FFFFFFFF(0-4G-1)
指针:指针就是地址,地址就是指针
指针变量是存放内存单元地址的变量
指针的本质是一个操作受限的非负整数

例题:
1 # include <stdio.h> 2 int main(void) 3 { 4 int * p;//p是个指针变量,int * 表示该p变量只能存储int类型变量的地址 5 int i = 10; 6 int j; 7 p = &i; 8 j = *p; 9 printf("%d\n", j); //j = *p; <=> j = i 10 return 0; 11 } 12 /* 13 在vc++6.0中的输出结果: 14 */
如何通过被调函数修改主调函数中普通变量的值
I实参为相关变量的地址
II形参为以该变量的类型为类型的指针变量
III在被调函数中通过 *形参变量名 的方式就可以修改主调函数中的变量
例题:
1 # include <stdio.h> 2 void f(int i) 3 { 4 i = 100; 5 } 6 int main(void) 7 { 8 int i = 9; 9 f(i); 10 printf("i=%d\n", i); 11 } 12 /* 13 在vc++6.0中的输出结果:i=9 14 */
例题:
1 # include <stdio.h> 2 void f(int * p) 3 { 4 *p = 100;//*p = i 5 } 6 int main(void) 7 { 8 int i = 9; 9 f(&i); 10 printf("i=%d\n", i); 11 } 12 /* 13 在vc++6.0中的输出结果:i=100 14 */
例题:
1 # include <stdio.h> 2 void f(int **); 3 int main(void) 4 { 5 int i=9; 6 int *p = &i; 7 printf("%p\n", p); 8 f(&p); 9 printf("%p\n", p); 10 return 0; 11 } 12 void f(int ** q) 13 { 14 *q = (int *)0xFFFFFFFF; 15 } 16 /* 17 在vc++6.0中的输出结果:0061FF2C 18 FFFFFFFF 19 */
总结:要想改变主调函数中某个变量的值,就必须要将变量地址发送给被调函数。
例题:主调函数调用被调函数来修改主调函数中数组中的内容
1 # include <stdio.h> 2 void Show_Array(int * p, int len) 3 { 4 p[0] = -1;//p[0] == *p 5 p[2] = -2;//p[2] == *(p+2) == *(a+2) 6 //p[i]就是主函数的a[i] 7 } 8 int main(void) 9 { 10 int a[5] = {1, 2, 3, 4, 5}; 11 printf("a[3]=%d, *(a+3)=%d\n", a[3], *(a+3)); 12 Show_Array(a, 5);//a等价于&a[0], &a[0]本身就是int * 类型 13 printf("%d\n", a[0]); 14 printf("%d\n", a[2]); 15 return 0; 16 }
如何通过被调函数修改主调函数中一维数组的内容
两个参数:存放数组元素的指针变量,存放数组元素长度的整形变量
2.结构体
(1)为什么会出现结构体
为了表示一些复杂的数据,而普通的基本类型变量无法满足要求。
(2)如何使用结构体
结构体是用户根据实际需要自己定义的复合数据类型。
(3)注意事项
结构体变量不能加减乘除,但可以相互赋值
结构体变量和结构体指针变量作为函数参数传递的问题
例题:通过变量名.结构体成员访问
1 # include <stdio.h> 2 # include <string.h> 3 //结构体定义了数据类型,数据类型是struct Student, sid name age是结构体成员 4 struct Student 5 { 6 int sid; 7 char name[200]; 8 int age; 9 };//分号不能省略 10 int main(void) 11 { 12 //整体赋值 13 struct Student st = {1000, "zhangsan", 20}; 14 printf("%d %s %d\n",st.sid ,st.name , st.age); 15 //单个赋值 16 st.sid = 99; 17 strcpy(st.name, "lishi"); 18 st.age = 20; 19 printf("%d %s %d\n",st.sid ,st.name , st.age); 20 return 0; 21 }
例题:通过结构体指针变量->结构体成员变量的方式访问
1 # include <stdio.h> 2 # include <string.h> 3 # include <malloc.h> 4 //结构体定义了数据类型,数据类型是struct Student, sid name age是结构体成员 5 struct Student 6 { 7 int sid; 8 char name[200]; 9 int age; 10 };//分号不能省略 11 int main(void) 12 { 13 struct Student st = {1000, "wangwu", 30}; 14 struct Student * pst; 15 pst = &st; 16 pst->sid = 99;//pst->sid <=> (*pst).sid <=> st.sid 17 strcpy(pst->name, "zhaoliu") ; 18 pst->age = 35; 19 printf("%d %s %d", pst->sid, pst->name , pst->age); 20 return 0; 21 }
规定:pst->sid <=> (*pst).sid <=> st.sid
pst所指向的结构体变量中的sid这个成员
例题:
# include <stdio.h> # include <string.h> struct Student { int sid; char name[200]; int age; }; void f(struct Student * ); void g(struct Student ); int main(void) { struct Student st;//变量声明没有初始化,里面的值还是垃圾值 f(&st); g(st); return 0; } void f(struct Student * pst) { pst->sid = 2004;//(*pst).sid strcpy(pst->name, "黑神悟空2004"); pst->age = 500; } //这种方式耗内存、耗时间 不推荐 void g(struct Student st) { printf("%d %s %d", st.sid, st.name, st.age); }
改良程序:
# include <stdio.h> # include <string.h> struct Student { int sid; char name[200]; int age; }; void f(struct Student * ); void g(struct Student *); int main(void) { struct Student st;//变量声明没有初始化,里面的值还是垃圾值 f(&st); g(&st); return 0; } void f(struct Student * pst) { pst->sid = 2004;//(*pst).sid strcpy(pst->name, "黑神话悟空"); pst->age = 500; } //这种方式耗内存、耗时间 不推荐 void g(struct Student * pst) { printf("%d %s %d", pst->sid, pst->name, pst->age); }
3.动态内存的分配和释放
# include <stdio.h> # include <malloc.h> int main(void) { //定义静态数组 int a[5] = {4, 10, 2, 8, 6}; //动态分配内存 int len; printf("请输入需要分配的数组的长度:len="); scanf("%d", &len); int * pArr = (int *)malloc(len * sizeof(int)); //malloc函数只能返回第一个字节的地址,此时地址没有实际意义,要进行强制转换(int*) *pArr = 4; //pArr[0] = 4 *(pArr+1) = 10;//pArr[1] = 10 *(pArr+2) = 2;//pArr[2] = 2 *(pArr+3) = 8;//pArr[3] = 8 *(pArr+4) = 6;//pArr[4] = 6 //我们可以把PArr当做一个普通数组来使用 for (int i=0; i<len; ++i) { scanf("%d", &pArr[i]); } for (int i=0; i<len; i++) { printf("%d ", *(pArr+i)); } free(pArr); //把pArr指向的动态分配的20个字节的内存释放 return 0; }
4.跨函数使用内存实例
# include <stdio.h> # include <malloc.h> struct Student { int sid; int age; }; struct Student * CreateStudent(void); void ShowStudent(struct Student * ); //函数声明是用";"结束 int main(void) { struct Student * ps; ps = CreateStudent(); ShowStudent(ps); return 0; } //定义CreateStudent()函数,返回值类型为struct Student * 类型 struct Student * CreateStudent(void) { struct Student * p = (struct Student *)malloc(sizeof(struct Student)); p->sid = 99; p->age = 100; return p; }; void ShowStudent(struct Student * pst) { printf("%d %d\n",pst->sid, pst->age); }

浙公网安备 33010602011771号