本章重点:结构体,指针。
我们一起来学习结构体..
为什么需要结构体呢 因为变量只能储存单一类型的数据 如果有关联的多种类型数据需要储存就会很乱,
比如说要存一个学生信息 名字,学号,电话,住址,成绩,班级 ;这些类型不同却又互相关联的数据我们用结构体来储存
首先结构体的定义与属性的访问
#includestruct student{ char name[20]; int stucode;}stu1;int main(){ struct student stu; stu.stucode=20; stu1.stucode=10; printf("%d\n",stu.stucode); printf("%d\n",stu1.stucode);}
从上面可以看到结构体的定义方式
1) 先定义结构体类型,再定义结构体类型变量:也就是stu;
2 ) 定义结构体类型同时定义结构体类型变量:也就是stu1;
3) 直接定义结构体类型变量:(这种方式一般都是一次性定义 很少使用):
struct { char name[20]; int stucode; } stu3; 该定义方法由于无法记录该结构体类型,所以除直接定义外,不能再定义该结构体类型变量
方法1,2之后想要声明变量都需要写struct student 变量名;是不是很麻烦?
这里有个 typedef 语法为 typedef 类型 你想要的变量名;
#includetypedef int I;int main(){ I i=1; printf("%d\n",i); }
再来看看结构体
#includetypedef struct{ char name[20]; int stucode;} Stu;int main(){ Stu stu; stu.stucode=20; printf("%d\n",stu.stucode);}
是不是简单多了呢?
继续学习...下面是C里面比较难一些的 指针
指针的作用:
指针可以用来有效地表示复杂的数据结构,可以用于函数参数传递并达到更加灵活使用函数的目的.使C语言程序的设计具有灵活、实用、高效的特点。
指针不仅仅是C语言的灵魂,运用得好更是事半功倍,让你写出的程序更简洁!(这个度娘说的更清楚);
指针类型的定义:类型 * 变量名;
内存其实分成很多空间,每个空间都有其地址,地址从1开始排也许能排几千亿甚至更多,
指针默认空间大小是八个字节,我们测试一下
#includeint main(){ int a=10; int * p; printf("%d\n",sizeof(int)); printf("%d\n",sizeof(p)); }
可能有人得到的是4个字节,因为你是32位系统,或者是32位的MinGW,64位的则是八个字节
指针到底怎么用呢?指针指向的是一个地址 我们都知道通过&变量名就能访问一个变量的地址,所有要指针指向变量的数据可以这样写
#includeint main(){ int a=10; int b=20; int * p=&a; printf("%p\n",&a); printf("%p\n",p); printf("%d\n",a); printf("%d\n",*p); p=&b; printf("%d\n",*p); printf("%p\n",&b); printf("%p\n",p); *p=30; printf("%d\n",*p); printf("%p\n",&b); printf("%p\n",p); }
通过以上代码可以了解到指针的简单使用*p能访问指向内存地址中的值,改变*p就能改变齐指向内存地址中的值,而p则是该指针指向的一个内存地址,改变p则改变地址
*p=30;等价于b=30;
以上都是指向变量的指针,下面看指向数组的指针
#includeint main(){ int a[20]; int* p=a; *p=20; printf("%p\n",p); p++; *p=30; printf("%p\n",p); p++; *p=40; printf("%p\n",p); printf("%d\n",a[0]); printf("%d\n",a[1]); printf("%d\n",a[2]); }
通过以上例子不难看出a本身就是数组的首地址,所以给指针赋值时没有增加&符号
根据每次p地址的输出可以看出p++并不是在p地址+1,而是在p地址加上一个int*p的大小 也就是4,每次赋值之后数组都往后挪一位;
指针用作函数参数比较多
#includevoid print(int *start,int* end){ while(start
这里定义了一个输出函数 能把传入的数组循环输出,参数是数组开始的地址和结束的地址,有人可能有疑问:首先length是什么?length是整个数组大小除以单个数的大小,
所以length是该数组的长度 a:则是数组开始的地址也就是首地址,a+length 数组长度就是数组结束地址,
最后解释下while循环内的输出语句
printf("%d\n",*start++); 等价于 printf("%d\n",*start); start++; 因为*运算符优先权高于++所以写在一起是先取*start输出在执行start++;
当然指针作为一个类型也可以当函数返回值..我们知道C语言函数返回值是没有数组的,所以我们只能返回数组的首地址
#includeint* print(int *a){ //处理过函数代码 return a;}int main(){ int a[]={ 3,3,3,2,4,5,3,2,4,5}; int*p=print(a);}
程序运行完之后指针p是指向数组a的首地址的(处理函数代码自己按需求脑补)
前面讲了那么多一直用的都是int类型指针 事实上指针类型有很多(char,float,double....) 指针要根据你给的类型判断内存中多少个字节放在一起处理
这里有个指针类型是 void 这是变量所没有的,那么void怎么用呢?
#includeint main(){ int a=2; float b=2.1; void*p; p=&a; printf("%d\n",*(int*)p); p=&b; printf("%lf\n",*(float*)p);}
void指针可以指向任何类型数据但如果你想使用void指针的数据就必须进行强转 如上面代码一样 原本是什么类型 取出时就强转成什么类型。