C语言程序设计学习笔记--指针
C语言程序设计学习笔记--指针。
8.1指针是什么
1.区分指针和指针变量:
? 指针:一个变量的地址称为该变量的“指针“,指针是一个地址。
? 指针变量:一个变量专门用来存放另一个变量的地址,指针变量是存放地址的变量。
2.举例:
变量i的指针是2000,不能说i的指针变量是2000
8.2指针变量
示例:
#include
int main()
{
int a=7,b=6;
int *p1;int *p2; //定义两个指针变量 p1,p2 *知识表示该变量是指针变量
p1=&a;
p2=&b;
printf("a=%d b=%d\n",a,b);
printf("p1=%d p2=%d",*p1,*p2); // “*p1 *p2”只是表示指针变量p1,p2所指向的变量
return 0;
}
1.定义: 类型名 *指针变量名int *p1,*p2; 基类型为Int的指针变量p1,p2;
例: float*p1 //定义float型变量的指针变量 简称float指针
Char*p2 //定义字符型变量的指针变量 简称char指针
Int*p3=&a,*p4=&b // 在定义的同时进行初始化
2.说明:
(1)定义指针变量时必须指定基类型,因为不同了类型在内存中字节数和存放方式不同。
(2)一个变量的指针含义包括两个方面;
? 以存储单元编号表示的地址
? 其指向的存储单元的数据类型
(3)指针变量中只能存放地址(指针),不能将一个整数付给一个指针变量,
例如: *p1=100 //不合法,p1指针变量,100是整数
3.引用:引用指针变量时,可能有三种情况
(1)给指针变量赋值 p = & a ; //把a的地址赋给指针变量p;
(2)引用指针变量指向的变量p=&a ; *p=1; //将正数1付给p当前所指的变量
(3)引用指针变量的值printf(“ % o “,p); 八进制数出指针变量p的值,如果p指向a,就输出a的地址,即 &a
示例:
#include
int main()
{
int *p1, *p2,*p;
int a = 5;
int b = 6;
p1 = &a;
p2 = &b;
if(a
{
p = p1;
p1 = p2;
p2 = p;
}
printf("thenumber a = %d b=%d\n",a,b);
printf("the max =%d the min = %d\n",*p1,*p2);
getchar();
return 0;
}
输出:
(1)printf("the max =%d the min = %d\n",*p1,*p2); //p1,p2所指向变量的值
(2)printf("the max = %dthe min = %d\n",p1,p2); //wrong
4.将指针变量作为函数参数
作用:将一个变量的地址传送到另一个函数中
示例:
#include
void swap(int *p1,int *p2)
{
int temp;
temp = *p1;
*p1 = *p2;
*p2 = temp;
}
int main()
{
void swap(int *p1,int *p2);
int *pp1, *pp2,*p;
int a = 5;
int b = 6;
pp1 = &a;
pp2 = &b;
printf("thenumber a1 = %d b1=%d\n",a,b); //在swap之前a1,b1
if(a
{
swap(pp1,pp2);
}
printf("\n");
printf("AfterSwitch\n");
printf("thenumber a2 = %d b2=%d\n",a,b); //swap之后a2,b2
printf("the max =%d the min = %d\n",*pp1,*pp2);//p1,p2存储的是a,b的地址,通过*指向
getchar();
return 0;
}
Swap 之前:a = 5; b = 6
Swap 之后: a = 6 ; b = 5
注意:不可以通过改变指针形参的值而实实参的值发生改变。
8.3通过指针引用数组
1.数组元素的指针
? 数组元素的指针就是数组元素的地址
示例:
P = &a[0] ; // p的值是a[0]的地址
P = a ;//p的值是数组a 首元素(即a[0])的地址
注意:
? 数组名不代表整个数组,只代表数组首元素的地址
? 定义指针变量时可以对它初始化int*p=&a[0]
? 在引用数组元素时指针的运算
当指针指向数组元素的时候允许对指针进行加 和 减 的运算。
P+1 P-1P++ P--
说明:
(1) 执行操作时不是给地址加1,而是加上一个数组元素所占用的字节数
(2) P的初值为&a[0],则p+1和a+i指向a数组序号为i的元素
(3) [ ] 实际是变址运算符,即将a[i]按a+i计算地址,找到地址单元中的值
2. 通过指针引用数组元素
? 引用一个数组元素有两种方法:
(1)下标法 a [ i ] P233页
(2)指针法 *( a+i),或者 *( p + i) . a数组名,p是指向数组元素的指针变量
#include
int main()
{
int a[10];
int *p, i;
printf("please input10 numbers");
for(i=0;i<10;i++)
scanf("%2d",&a[i]);
for(p=a;p<(a+10);p++) //将 p++改成a+=不可以
printf(" %2d",*p); // a代表数组元素首地址,是一个指针型常量,a++无法实现
return 0;
}
注意:
(1)可以通过改变指针变量的值指向不同的元素
(2)指向数组的指针变量可以带下标,因为编译时对下标的处理方法是转换为地址
对 p[ i ] 处理为 *(p+i ) //不推荐使用
区别混淆:
3.数组名做函数参数
区别:
? 实参数组名:代表一个固定的地址,按指针常量处理
? 形参数组名:并不是固定的地址,按指针变量处理
总结:
改变函数中数组中元素的值有以下四种情况
4.通过指针引用多维数组
8.4通过指针引用字符串
1 . 字符串的引用
字符串存放在字符数组中,引用一个字符串有两种方法 :
? 字符数组存放字符串,通过数组名和下标引用字符串中的某个字符,可以通过数组名和格式声明% s 输出该字符串。
? 字符指针变量指向一个字符串常量,通过字符指针变量引用字符串常量
2.字符指针作函数参数
3.字符指针变量和字符数组比较
(1)字符数组——元素中存放字符
字符指针变量——地址
(2)赋值方式——可以对字符指针变量赋值,但是不能对数组名赋值
(3)初始化,对字符指针变量赋初值
(4)存储单元内容:
? 字符数组——编译时分配若干单元,存放各个元素的值
? 字符指针变量——只分配一个存储单元
(5)指针变量的值——可以改变
数组名——代表一个固定的值(元素首地址),不能改变
char *a="I LOVE CHINAHAHAHA"; //空格也算是一个
a=a+7;
printf("%s \n ",a); //合法
若改为
Char str[]={"I LOVE CHINA HAHAHA"}; //空格也算是一个
Str=str+7;
printf("%s \n ",str); //非法 数组名代表地址,常量,不能改变
(6)字符数组中各个元素值可以通过赋值改变
Chara[ ] =”gaobo”;
a[2]=’d’;//合法
字符指针变量指向的字符串常量中的内容不能改变
Char*a=”gaobo”;
a[2]=’d’;//非法
8.5指向函数的指针
1.函数指针:存储空间的起始地址(入口地址)称为这个函数的指针
2.函数指针变量调用函数:
(1)通过函数名调用函数
(2)通过指针变量访问其所指向的函数
3.指向函数的指针变量
? 定义 :类型名(*指针变量名)(函数参数表列)
int ( * p ) ( int , int );
注意:
b.使用
4.用指向函数的指针作函数参数
把函数的地址作为参数传递到其他函数
8.6返回指针指的函数
一般形式: 类型名 *函数名(参数表列)
8.7指针数组和多重指针
1.指针数组: 类型名* 数组名[数组长度] int * p[4]
注意: int (*p)[4] //指向一维数组的指针变量
2.指针数组作为main函数的形参
8.8动态内存分配与它的指针变量
1.动态内存分配:
(1)定义:
程序执行的过程中动态地分配或者回收存储空间的分配内存的方法。动态内存分配不象数组等静态内存分配方法那样需要预先分配存储空间,而是由系统根据程序的需要即时分配,且分配的大小就是程序要求的大小。
(2)怎样建立内存的动态分配?
void *malloc(unsigned int size) //分配一个长度为size的连续空间
volid *calloc(unsigned n,unsigned size) //分配一个n*size的空间
void free(void *p) //释放指针变量p所指的以分配的动态空间
void *realloc (void *p ,unsigned int size) //改变已获空间的大小
2.Void指针类型:指向空类型或 不确定类型
遗留问题:
关于:字符指针变量和字符数组比较
理解
指针变量的值——可以改变
数组名——代表一个固定的值(元素首地址),不能改变
char *a="I LOVE CHINAHAHAHA"; //空格也算是一个
a=a+7;
printf("%s \n ",a); //合法
若改为
Char str[]={"I LOVE CHINAHAHAHA"}; //空格也算是一个
Str=str+7;
printf("%s \n ",str); //非法 数组名代表地址,常量,不能改变
字符数组中各个元素值可以通过赋值改变
Char a[ ] =”gaobo”;
a[2]=’d’; //合法
字符指针变量指向的字符串常量中的内容不能改变
Char*a=”gaobo”;
a[2]=’d’;//非法