一.指针
1.运算符&和*:
&:获取当前变量的地址,如scanf("%d",&n);中的&是获取变量n的地址
*:获取当前地址的变量
2.指针:
指针变量就是一个存储地址的变量,指针本质上是地址,地址是存放地址的变量
int i; //i是一个int类型的变量
int *p=i; //p是一个对i的指针变量,*p完全等同于变量i,在代码的所以地方i和*p可以互相替换
p=&i; //保留了i的地址,因此指针p指向i,但p不是i,i不是p
int *p,q; //p是指针,而q是一个int类型的普通变量
int* p,q; //上一行定义变量的不同表示方法
3.指针的运算:
指针的相加、相除和相乘都是无意义的,只有相减有意义(只有两个指针都指向同一个数组时指针才有意义),指针的相减表示两个变量的地址指针之间的距离(以数组元素的个数衡量),但指针可以加一个数也可以减一个数,当指针加一表示指针指向下一个变量
4.函数应用场景一:
当函数返回一个值时,可以使用return;当函数返回多个值时,某些值只能通过指针返回
#include <stdio.h>
void minmax(int a[],int len,int *max,int *min); //函数声明
int main()
{
int a[]={1,2,3,4,5,6,7,8,9,12,13,14,16,17,18,22,24,25};
int min,max;
minmax(a,sizeof(a)/sizeof(a[0]),&min,&max); //数组长度等于数组所含字节数除以数组一个单元
printf("min=%d,max=%d\n",min,max); //的字节数
return 0;
}
void minmax(int a[],int len,int *min,int *max) //自定义识别最大值最小值的函数
{ //函数参数表里的数组就是指针,即a[]与*a等价,因此a[]
int i; //的中括号里面不管有没有数字都表示数组的地址
*min= *max=a[0];
for(i=1;i<=len;i++)
{
if(a[i]<*min)
*min=a[i];
if(a[i]>*max)
*max=a[i];
}
}
5.指针运用场景二:
函数返回状态(如判断除法是否成立),指针返回结果
#include <stdio.h>
int divide(int a,int b,int *result);
int main()
{
int a,b,c;
scanf("%d %d",&a,&b);
if(divide(a,b,&c))
{
printf("%d/%d=%d",a,b,c);
}
return 0;
}
int divide(int a,int b,int *result) //除法成功返回1,否则返回0
{
int ret=1;
if(b==0)
ret=0;
else
*result=a/b;
return ret;
}
6.关于指针的指向,当定义一个指针没有指向变量时,指针变成了野指针,极易导致程序崩溃
7.const指针:
当const指针得到某一个变量的地址,不能再指向其他变量,即指向变量的地址无法改变
int * const q=&i; //q是const
*q =26; //地址无法改变,但当前地址对应的值可以改变
q++; //语法出错
当指针是const int类型时,不能通过修改指针去改变所指的变量的值
const int *p=&i; //定义指针变量p
*p=26; //语法错误,由于指针变量p已被初始化,无法再被复制
i=26; //可以,i可以被赋值
p=&j; //由于指针p不是const指针,p可以取另一个变量的地址8
8.关于0地址:
内存中由0地址,但0地址通常是个不能随便碰的地址,所以指针不应该由0值,但是0地址可以表示特殊的事情,如返回的指针时无效的、指针没有被真正初始化(先初始化为0),NULL时一个预定定义的符号,表示0地址
二.结构体
1.枚举:
枚举是一种用户定义的数据类型,它用关键字enum声明(如下):
enum 枚举类型名字{名字0,名字1,...,名字n};
枚举类型名字通常并不真的使用,要用的是大括号里面的名字 ,因为他们就是常量符号,类型是int,值则依次从0到n,如:
enum colors{red,yellow,green}; //创建了三个常量,red的值是0,yellow是1,green是2
//此枚举类型名字是colors,即colors枚举类型
2.结构体的用处:再一个结构体内使用多种变量类型,用一个变量来输出不同的结变量类型
#include <stdio.h>
struct date //在函数外面声明结构类型,可以被多个函数使用
{
int month;
int day;
int year;
};
//结构初始化:struct date today={07,31,2014};
//或struct date thismonth={.monthe=7,.year=2014};
//上一行编译器默认thismonth.date=0
int main()
{
struct date today; //定义一个结构类型date的结构变量today
today.month=07;
today.day=31;
today.year=2014;
printf("Today's date is %i-%i-%i.\n",today.year,today.month,today.day);
return 0; //%i和%d的用法一致,通常情况下使用%d
}
3.结构体使用示例:
输入三个人的语数英三科成绩,找出数学成绩最高的人,输出他的数学成绩和名字
4.结构嵌套:
由于结构类型也是一种变量类型,所以结构体中也可以使用结构变量作为成员变量
使用示例:运用结构体嵌套打出一个人的基本信息
#include<stdio.h>
struct date //定义结构中的结构
{
int year;
int month;
int day;
};
struct student //定义结构
{
char name[10];
int age;
float score;
struct date birthday; //结构嵌套
}stu1={"周小星",50,95.0,1962,6,22}; //可以定义一个结构变量stu2,与数组不同,可讲stu2直接赋值
int main() //给stu2
{
printf("名字是%s\n年龄是%d岁\n成绩是%.1f分\n",stu1.name, stu1.age, stu1.score);
printf("出生日期为%d年%d月%d日",stu1.birthday.year, stu1.birthday.month, stu1.birthday.day);
} //外层结构体指向成员变量,内层结构体再指向成员变量
注: 学习资源来自翁恺