指针篇
一、什么是指针:
指针 = 地址
-
取地址(&hello) //&取地址 取变量名所代表的变量的内存地址
-
若要取地址里面的值:*(&hello); // 此时 " * "代表的是一个运算符,跟+ - / * 运算符类似,该运算符的功能是取出内存地址中的数据的值(取内容)。
-
int 整型变量 存放的是整数 char 字符变量 存放的是字符 int array[3]={1,2,3};数组 存放的是一串数据
问:什么变量能存放地址呢? 答:指针变量存放的是地址。
二、如何定义指针变量:
int *p; //指针变量 存放的就是地址
p = &a; //给指针变量赋值。
int *p2 = &a; //定义并且初始化一个指针变量
三、指针的概念总结:
-
变量的访问有两种方式 :
第一种: 变量名 (如花店名,你可以一路以花店的名字问路找到花店)
第二种: 取地址 (取变量名所代表的变量的内地址)
如 int a =10 ; &a(0x660cffc0) -
此时 " * "代表的是一个运算符,跟+ - / * 运算符类似,该运算符的功能是取出内存地址中的数据的值(取内容)。
int a =10; a是变量名 *(&a) 地址 -
变量
整型变量 存放的是整数 int a; a=10;
字符变量 存放的是字符 char c; c=‘A’;
指针变量存放的是地址 int *p =&a; char *p; p=&c;
只有在定义一个指针变量的时候,才是指针的一个标识符,在其他情况,都是一个取内容的运算符
指针 = 地址
指针变量 1.存放指针的变量 2.存放地址的变量
四、通过指针来访问变量
int *p1; //标签 代表是一个指针变量
p1 = &hello;
printf("hello的地址是:%p\n ",p1 ); //&取地址 ,取变量名所代表的变量的内存地址。
int *p2 = &meiguitai;
printf(“通过mei的地址来获取mei=%d\n” , *p2); //*取内容符,取变量名所代表的变量的内存地址内的值。
五、指针的使用:
指针分类型
- 指针与整数:
int *p;int a=10; p = &a; //整型指针只能指向整型数据 ,只能存放整型地址。
printf(" a = %d \n " , *p); //用指针来访问数据值
int *p; char c=‘A’; p=&c; //在判断计算机的大小端
- 指针与数组:
数组: int array[3]={1,2,3}; //数组,关心的是数组的首地址
printf(“第一个元素的地址是%p\n”,&array[0]);
printf(“第二个元素的地址是%p\n”,&array[1]);
printf(“第三个元素的地址是%p\n”,&array[2]);
- 若要遍历来查看数组的地址:
int array[3]={1,2,3};
for(i=0;i<3;i++){
printf("%d",array[i]);
}
六、为什么用指针?
- 指哪打哪——指定内存位置,给它赋值
- 经典数据交换——参数传递要用地址
案例二:强制保持在我要的地址 0060ff00
int *p = (int *)0x0060ff00; //强制保存在我要的地址 0060ff00
*p = 10;
printf("在内存的%p位置,存放值是%d\n"p,*p);
volatile int *p = (volatile int *)0x0060ff00; //强制保持在我要的地址0060ff00
若要用函数来封装交换:(需要用指针)
void swap (int *a ,int *b){
int tmp;
tmp = *a; //这里的*a是取内容
*a = *b;
*b=tmp;
}
int main(){
int a=10;
int b=5;
swap(&a,&b); //调用交换函数
return 0;
}
七、指针的重点:
-
变量访问的两种方式:
a.变量名 b.指针 -
指针
a.指向谁(类型)p=&a
b.偏移后指向谁 p++ -
整型指针只能指向整型数据,只能存放整型地址
八、指针数组:
-
int *parry; parray = &array[0]; //也可以写 parray =array; 因为数组名也是地址
printf(“第一个元素的地址是%p\n”,parray++); //打印的是指针数组第一个元素地址
printf(“第二个元素的地址是%p\n”,parray++); //打印的是指针数组第二个元素地址
printf(“第三个元素的地址是%p\n”,parray++); //打印的是指针数组第三个元素地址
若要遍历来查看指针数组的地址:
int *parray ;
parray = &array[0];
for(i=0;i<3;i++){
printf("%d",*parray); //也可以写成printf ("%d",parray[i]);
}
案例一:指针数组函数的综合的案例:
#include<stdio.h>
//初始化数组函数
void initscores(int *array,int size){
int i;
for(i=0;i<size;i++){
printf("请输入第%d个学生成绩\n",i+1);
scanf_s("%d",array);
if(*array<0 || *array>100){ //在双条件判断的时候用 ”||”(或)
printf("输入成绩错误,请重新输入\n");
exit(-1);
}
}
}
//打印数组函数
void scoreprint(int *array,int size){
int i;
for(i=0;i<size;i++){
printf("请输入第%d个学生成绩为%d\n",i+1,*array++);
}
}
//找到最高分
int Maxvalue(int *array,int size){
int j;
int max = *array;
for(j=0;j<size;j++){
if(max < *array){
max = *array;
}
array++;
}
printf("最高分是%d\n",max);
}
//找到最低分
int Minvalue(int *array,int size){
int j;
int min = *array;
for(j=0;j<size;j++){
if(min > *array){
min = *array;
}
array++;
}
printf("最低分是%d\n",min);
}
//算出平均分
void average(int *array,int size){
int add = 0;
float average;
int i;
for(i = 0 ; i<size; i++){
add +=*array;
}
arrayage=(float)add / 10;
printf("平均值为%d",average);
}
int main(){
//定义数组
int scores[10]={0};
int len = sizeof(scores) / sizeof(scores[0]);
//初始化数组
intitscores(scores,len);
//打印数组
scoreprint(scores,len);
//找到最高分
Maxvalue(scores,len);
//找到最低分
Minvalue(scores,len);
//算出平均分
average(scores,len);
return 0;
}
int array[3]; //多个整数,叫做整数数组
定义指针数组:
int a=2;
int b=3;
int *parray[3];
parray[0]=&a;
parray[1] = &b;
int i;
for(i=0;i<30;i++){
printf("%d",*(parray[i]));
}
九、数组指针:
定义数组指针: int (*p)[3]; //数组的指针
给数组指针赋值:p =a;
int main(){
int a[3]={1,2,3};
int *p; //此指针并非是数组指针,仅仅是一个普通的整型数的指针,刚好指向了数组的首元素地址
p=a;
int i;
for(i=0;i<3;i++){
printf("%d",*p++);
}
}
十、函数指针
- 如何定义一个函数指针?
void(*p)( );
类型(*指针变量名)(函数参数); 如:int (*p)( int x , int y);
- 如何给函数指针赋值?
函数名就是地址
void printWelcome()
{
printf("欢迎来到函数指针学习课堂\n");
}
int main(){
void *p();
p = printWelcome; //函数就是地址 ,就像数组一样,数组名就是地址
}
- 如何通过函数指针调用函数?
p( ); //直接通过 名字( );
(*p)( ); //取内容(*指针名字) ( ) - 用指向函数的指针作函数参数:
指向函数的指针变量的一个重要用途是把函数的地址作为参数传递到其他函数
如: void fun ( int (*x1)(int x) , int (x2)(int x ,int y)); - 返回指针值的函数
类型名*函数名(参数)
int *p( )
十一、无类型指针(void) 无类型&&malloc
//正常数组定义
int main(){
int *a=(int *)malloc(3*sizeof(int)); //也是数组
int i;
for(i=0;i<3;i++){
a[ i ]=i;
}
for(i=0;i<3;i++){
printf("%d",a[ i ] );
}
}
......................................................................
int main(){
int n;
printf("请输入整型数组元素的个数\n");
scanf("%d",&n);
int *parray = (int *)malloc(n*sizeof(int)); //数组
if(parray == NULL){
printf("开辟空间失败");
}
int i;
for(i=0;i<n;i++){
printf("请输入第%d个学生的成绩:",(i+1));
scanf("%d",&parry[i]);
}
for(i=0;i<n;i++){
printf("第%d学生的成绩:",(i+1),*parray[i]);
}
}
无类型的指针 :一个指针变量 不知道指向的空间是什么属性
十二、关于malloc的面试问题:
malloc如何使用?
指针变量 = (强制类型)malloc(大小)
如:int *p = (int *)malloc (3 * sizeof ( int ) ); //也是一种数组的定义方式
free(指针变量名);
free是释放内存空间的函数,通常与申请内存空间的函数malloc()结合使用,可以释放由malloc(); 、calloc();、realloc();等函数申请的内存空间。