变量地址的意义
指针的定义
指针的赋初值
通过指针改变变量的值
内存:(锅)
A:在计算机中有一个很大的处理场
B:程序都是在内存中运行的
C:总结:数据的处理场地
外存:(电冰箱)数据的存放场地
当我们编写一个c程序,并运行后,它也会放在内存中
什么是指针:
1、c程序要运行,都是在内存中来运行的
2、在c程序中一般会有很多变量,windows就会为程序中的每一个变量分配一个存储单元,
3、因为内存比较大,为了方便管理windows就会把内存分成很多小块单元,这个单元被称为存储单元。
4、存储单元就是一个小区域
5、存储单元为了以后便于区分,他们也会编址
6、 int a ;
A:windows马上为这个变量分配一个存储单元
B:a=5 windows 会马上通过变量名a找到为变量a分配存储单元,然后把值5放入那个单元中去。
C:以前一直都认为5会把值赋给变量a变量a是不能存储值的,应该是把5放到为a分配的存储单元中
7、以前都是通过变量名去找到该变量分配存储单元
8、以前要为变量赋值实际上经过2步
找变量分配的存储单元(地址)
再把值写入到那个地址中
9、把通过变量名找到地址,然后为地址赋值的方式被称为间接方式,效率比较低
10、 a=a+1
先从a的地址中读取a的值
再把值加一后重新写到那个存储单元
11、指针:
指针就是地址
指针变量:
指针变量他是一个变量,,用来存储地址的变量被称为指针变量
这个变量里面以后只能存储地址。而不能存储值
定义的指针:
类型标识符 *指针名;
比如: int *p;
定义了一个指针p以后这个指针变量,只能存储地址,不能存储值。而且它只能存储普通整型变量的地址。
定义指针的类型标识符:
他是用来决定指针以后能存储的地址对应的变量的类型
给指针赋初值
只能把地址赋给指针
两种方式:
A:在定义的时候赋初值
int a=3,*p=&a;的地址
B :zai 定义之后,再赋初值
int a=3,*pa; 这里的*是定义时的*
pa=&a; 指针是pa
scanf("%d",&a);取地址符
在指针有一个符号非常重要*
1、 根据场合的不同,它的意义也不一样
2、 两种场合:
A:在定义的时候,*号代表一个标识,表明该变量是一个指针变量
B:在定义之后,*号就代表指针所指向的变量
3、 如果把变量a的地址赋给指针p ,那么我们就说,指针p就指向变量a
int a=3,*pa;
pa=&a;
*pa=*pa+1; //通过指针来改变变量的值的方式,称为直接方式。
printf("a=%d,*pa=%d",a,*pa);//a=4,*pa=4
4、 几个表达式:
6、 指针p指向变量a,那么*p就相当于a
指针的应用举例
指针现在指向何方?
指针是如何进行变化的
*指针究竟是谁
要使指针指向发生变化,必须要重新把地址赋给指针 p2=p1
要使指针执行*的操作,它变化的是变量的值,而不是指针
*p2=*p1;
int a=3,b=4,*pa=&a,*pb=&b;
pb=pa;
pa--->a<----pb
以指针作为函数参数
以指针作为函数参数的格式
1: 整型变量int,实型变量float,字符型变量char都可以作为函数参数
2: 指针实际上是变量,所有指针也可以作为函数的参数
3: 格式:
类型标识符 函数名(指针)
{
代码;
}
例子:
注意以下几点:
A:两种传值方式:
实参把值传给了型参: 传值方式 //型参的改变不会影响实参
实参把地址传给了型参: 传址方式 //型参的改变可能会影响实参
指针作为函数参数的方式
一维数组的指针,指向一维数组的指针
以指针作为函数参数的应用举例
例1:
编写一个函数,用来判断是一个数n是否是质数
一维数组的指针与指向一维数组元素的指针*********
1、 数组名代表数组的首地址,是常量,常量不能自加 。 变量才能自加
2、*(a+i) =a[i] 或a[i]=*(a+i) 只是对于一维数组而言
*a=a[0]
3、 一维数组名a永远指向a[0],并且不能改变
4、 尽管数组名a是指针,但是这个指针是常量,不能移动,为了能够产生一个可以移动的指针,
那我们就要定义一个指向一维数组元素的指针(变量)
5、 指针可以比较大小,但只限于在数组中,上面的指针都会比下面的指针小
6、 如何通过指针来访问一维数组的所有元素
for(p=数组名;p<a+数组元素个数;p++)
{
*p就代表数组中的每一个元素
}
只有字符串才有\0 ,整型数组没有
int a[4]={12,34,56,78}; a--> a[0] 12 a=&a[0] 数组名本身就是指针
a+1--> a[1] 34
a+2--> a[2] 56
a+3--> a[3] 78 指针指向谁,*指针就等于谁
*(a+i) =a[i]
*(a+i) =a[i]
a[i]=*(a+i)
指向一维数组的指针
指针的定义
指针的赋初值
通过指针改变变量的值
内存:(锅)
A:在计算机中有一个很大的处理场
B:程序都是在内存中运行的
C:总结:数据的处理场地
外存:(电冰箱)数据的存放场地
当我们编写一个c程序,并运行后,它也会放在内存中
什么是指针:
1、c程序要运行,都是在内存中来运行的
2、在c程序中一般会有很多变量,windows就会为程序中的每一个变量分配一个存储单元,
3、因为内存比较大,为了方便管理windows就会把内存分成很多小块单元,这个单元被称为存储单元。
4、存储单元就是一个小区域
5、存储单元为了以后便于区分,他们也会编址
6、 int a ;
A:windows马上为这个变量分配一个存储单元
B:a=5 windows 会马上通过变量名a找到为变量a分配存储单元,然后把值5放入那个单元中去。
C:以前一直都认为5会把值赋给变量a变量a是不能存储值的,应该是把5放到为a分配的存储单元中
7、以前都是通过变量名去找到该变量分配存储单元
8、以前要为变量赋值实际上经过2步
找变量分配的存储单元(地址)
再把值写入到那个地址中
9、把通过变量名找到地址,然后为地址赋值的方式被称为间接方式,效率比较低
10、 a=a+1
先从a的地址中读取a的值
再把值加一后重新写到那个存储单元
11、指针:
指针就是地址
指针变量:
指针变量他是一个变量,,用来存储地址的变量被称为指针变量
这个变量里面以后只能存储地址。而不能存储值
定义的指针:
类型标识符 *指针名;
比如: int *p;
定义了一个指针p以后这个指针变量,只能存储地址,不能存储值。而且它只能存储普通整型变量的地址。
定义指针的类型标识符:
他是用来决定指针以后能存储的地址对应的变量的类型
给指针赋初值
只能把地址赋给指针
两种方式:
A:在定义的时候赋初值
int a=3,*p=&a;的地址
B :zai 定义之后,再赋初值
int a=3,*pa; 这里的*是定义时的*
pa=&a; 指针是pa
scanf("%d",&a);取地址符
在指针有一个符号非常重要*
1、 根据场合的不同,它的意义也不一样
2、 两种场合:
A:在定义的时候,*号代表一个标识,表明该变量是一个指针变量
B:在定义之后,*号就代表指针所指向的变量
3、 如果把变量a的地址赋给指针p ,那么我们就说,指针p就指向变量a
int a=3,*pa;
pa=&a;
*pa=*pa+1; //通过指针来改变变量的值的方式,称为直接方式。
printf("a=%d,*pa=%d",a,*pa);//a=4,*pa=4
4、 几个表达式:
(1) k=*p++; //先把*p的值赋给变量之后 p+1 指针加一,就表示指针会向下移动一个单位
void main()
{
int a=3,*pa;
pa=&a;
k=*pa++;//k=*pa,之后指针pa+1
printf("a=%d,k=%d,*pa=%d",a,k,*pa);//a=3,k=3,*pa=不定的值
}
(2) k=(*pa)++;先把*p的值赋给k,*pa+1
//相当于k=*pa ,然后*pa=*pa+1
void main()
{
int a=3,*pa;
pa=&a;
k=(*pa)++;//k=*pa,之后指针*pa+1
printf("a=%d,k=%d,*pa=%d",a,k,*pa);//a=4,k=3,*pa=4
}
(3) k=++(*pa);//先把*p的值加一,之后再把*p的值给k
相当于*pa=*pa+1 ,然后k=*pa
void main()
{
int a=3,*pa;
pa=&a;
k=++(*pa);//k=*pa+1,之后指针pa+1
printf("a=%d,k=%d,*pa=%d",a,k,*pa);//a=4,k=4,*pa=4
}
(4)k=*(++p); //先把指针p+1之后,再把*p的值赋给变k
void main()
{
int a=3,*pa;
pa=&a;
k=*(++pa);//z指针pa+1,指针pa就不再指向a, 之后k=*pa
printf("a=%d,k=%d,*pa=%d",a,k,*pa);//a=3,k=不定,*pa=不定
}
5、 谁把变量的地址赋给了指针p,那么p就指向谁
6、 指针p指向变量a,那么*p就相当于a
指针的应用举例
main()
{
int a=3,b=4,*pa=&a,*pb=&b;//这边的*是定义时的*
// *pa=&a;//错了,pa是一个指针,是一个地址,*pa是指针pa指向的变量的值,&a是地址,地址不能赋值给值
pb=&a;
pa=&b;
*pa=*pb+b;
*pb=*pa+a;
printf("a=%d,b+%d,*pa=%d.*pb=%d",a,b,*pa,*pb);//10,7,7,10
}
void main()
{
int a=3,b=4,*pa,*pb,*t;
pa=&a;
pb=&b;
t=pa;
pa=pb;
pb=t;
*pa=*pb+b;
*pb=*pa+a;
printf("a=%d,b+%d,*pa=%d.*pb=%d",a,b,*pa,*pb);//10,7,7,10
}
void main()
{
int a=3,b=4,c=5,*pa=&a,*pb=&b,*pc=&c;
pb=&c;
pc=&a;
pa=&b;
if(*pa>*pb)
{
pb=pc;
}else
{
pa=pb;
}
*pa=*pb+*pc;
*pb=*pa+*pc;
*pc=*pa+*pb;
printf("a=%d,b=%d,c=%d,*pa=%d,*pb=%d,*pc=%d",a,b,c,*pa,*pb,*pc);//
}
总结:
指针现在指向何方?
指针是如何进行变化的
*指针究竟是谁
要使指针指向发生变化,必须要重新把地址赋给指针 p2=p1
要使指针执行*的操作,它变化的是变量的值,而不是指针
*p2=*p1;
int a=3,b=4,*pa=&a,*pb=&b;
pb=pa;
pa--->a<----pb
以指针作为函数参数
以指针作为函数参数的格式
1: 整型变量int,实型变量float,字符型变量char都可以作为函数参数
2: 指针实际上是变量,所有指针也可以作为函数的参数
3: 格式:
类型标识符 函数名(指针)
{
代码;
}
例子:
void fun(int *p)
{
if(*p>5)
{
*p=*p+1;
}
else
{
*p=*p-1;
}
}
void fun1(int a)
{
if(a>5)
{
a=a+1;
}
else
{
a=a-1;
}
}
int sum(int *a,int *b,int *s)
{
*s=*a+*b;
}
void main()
{
int a=2,save;
fun(&a);//实参把地址传给了型参
printf("a=%d",a); //a=1
fun1(a);// 实参把值传给了型参:
printf("a=%d",a); //a=1
}
//
void sum(int *a,int *b,int *s)
{
*s=*a+*b;
}
void swap(nt *a,int *b,int *s)
{
int t;
t=*a;
*a=*b;
*b=t;
}
void main()
{
int a=2,b=4,s;
sum(&a,&b,&s);
printf("s=%d",s); //s=6
swap(&a,&b);
}
注意以下几点:
A:两种传值方式:
实参把值传给了型参: 传值方式 //型参的改变不会影响实参
实参把地址传给了型参: 传址方式 //型参的改变可能会影响实参
指针作为函数参数的方式
一维数组的指针,指向一维数组的指针
以指针作为函数参数的应用举例
例1:
编写一个函数,用来判断是一个数n是否是质数
int isPrimer(int *n)
{
int i;
for(i=2;i<n;i++)
{
if(*n%i==0)
return false;
}
return true;
} //while(n)==while(n!=0)
void main()
{
int a;
printf("请输入一个整数:");
scanf("%d",&a);
if(isPrimer(int *n))
{
printf("是质数);
}else{
printf("不是质数);
}
}
//写一个函数,求两个数的绝对值的和
int abs(int *n)
{
if(*n>0)
return *n;
return -*n;
}
int sum(int *a,int *b)
{
return abs(*a)+abs(*b);
}
void main()
{
int a=3,b=4,s=0;
s=sum(&a,&b);
printf("s=%d",s);
}
一维数组的指针与指向一维数组元素的指针*********
1、 数组名代表数组的首地址,是常量,常量不能自加 。 变量才能自加
2、*(a+i) =a[i] 或a[i]=*(a+i) 只是对于一维数组而言
*a=a[0]
3、 一维数组名a永远指向a[0],并且不能改变
4、 尽管数组名a是指针,但是这个指针是常量,不能移动,为了能够产生一个可以移动的指针,
那我们就要定义一个指向一维数组元素的指针(变量)
5、 指针可以比较大小,但只限于在数组中,上面的指针都会比下面的指针小
6、 如何通过指针来访问一维数组的所有元素
for(p=数组名;p<a+数组元素个数;p++)
{
*p就代表数组中的每一个元素
}
只有字符串才有\0 ,整型数组没有
int a[4]={12,34,56,78}; a--> a[0] 12 a=&a[0] 数组名本身就是指针
a+1--> a[1] 34
a+2--> a[2] 56
a+3--> a[3] 78 指针指向谁,*指针就等于谁
*(a+i) =a[i]
*(a+i) =a[i]
a[i]=*(a+i)
void main()
{
int a[5]={1,2,3,4,5},k1,k2,k3;
//a是常量,永远不能改变
k1=*a**a+1; //1*a[0]+1=2
k2=*a**(a+1);//1*a[1]=2
k3=*a*(*a+1);//1*2=2
printf("k1=%d,k2=%d,k3=%d",k1,k2,k3);
}
void main()
{
int a[5]={1,2,3,4,5},*p;//a是常量,永远不能改变 a--> a[0]
p=a; //或者p=&a[0]; a+1--> a[1] <--p
p++; a+2--> a[2]
a+3--> a[3]
*(a+i) =a[i]
printf("*p=%d",*p);
}
void fun(flat *a,float *b)
{
float w;
*a=*a+*a;
w=*a;
*a=*b;
*b=w;
}
main()
{
float x=2.0,y=3.0;
float *px=&x,*py=&y;
fun(px,py);
printf("x=%.1f,y%.1f",x,y);//x=3.0,y=4.0
}
********************************
void sub(int x,int y,int *z)
{
*z=y-x
}
main()
{
int a,b,c;
sub(10,5,&a);//a=-5
sub(7,a,&b);//b=-12
sub(a,b,&c);//c=7
printf("a=%d,b=%d,c=%d",a,b,c);
}
/***************
void sub(float x,float *y,float *z)
{
*y=*y-1;
*z=*z+x;
}
main()
{
float a=2.5,b=9.0,*pa,*pb;
pa=&a; pa--->a(2.5)
pb=&b; pb--->b(9.0)
sub(a-b,pa,pb);
printf("a=%.1f",a);//1.5
}
********************************
动态数组:就表示在定义数组时,不指定数组的长度,这样这个数组就可以根据赋值的多少,长度动态的发生改变
main()
{
int a[]={1,2,3,4,5,6,7,8,9,0},*p;
p=a;
printf("%d\n",*p++);//先引用*p的值,然后p再+1,这时p指向a[1]
printf("%d",*(P+3)); p指向a[4]
key 1
*
}
main()
{
int s[]={1,2,3,4,5,6},*p=s+3;//a[2]=*(a+2) *(a+i)=a[i]
printf("%d",p[2]);//6
}
main()
{
int a[]={1,2,3,4,5,6},*p;
for(p=a;p<a+6;p++)
{
printf("%d",*p);
}
}
指向一维数组的指针
main()
{
int a[]={2,4,6,8,10},y=1,x,*p;
p=&a[1];
for(x=0;x<3;x++)
{
y+=*(p+x);//1+4+6+8
}
printf("y=%d",y);//19
}
main()
{
int a[]={2,4,6,8,10,12,14,16,18},y=1,x,*p;
p=&a[2];
printf("p[3]=%d",p[3]);//12 p[3]=*(p+3)
}
void sum(int *a)
{
a[0]=a[1]; //*(a+0)=*(a+1)
}
main()
{
int aa[4]={1,2,3,4},i;
for(i=2;i>=0;i--)
{
sum(&aa[i])
}
printf("aa[0]=%d",aa[0]);
}
void func(int *a,int b[])
{
b[0]=*a+6;
}
main()
{
int a,b[5]={0};
a=0;
b[0]=3;
func(&a,b);
printf("b[0]=%d",b[0]);
}
//程序功能,利用指针实现数组a的元素倒置
void fun(int *x,int *y)
{
int t;
t=*x;
*x=*y;
*y=t;
}
main()
{
int a[8]={1,2,3,4,5,6,7,8},*p,*q,i;
p=a;
q=&a[7];
while(p<q)
{
f(p,q);
p++;
q--;
}
for(i=0;i<8;i++)
{
printf("%d",a[i]);
}
}
//把数组a中的所有素数加起来。
int isPrimer(int *n)
{
int i;
for(i=2;i<n;i++)
{
if(*n%i==0)
return 0;
}
return 1;
}
main()
{
int a[10]={11,34,45,56,67,78,89,23,12,32},*p=a,s=0;
for(;p<a+10;p++)
{
if(isPremer(p))
{
s+=*p;
}
}
printf("s=%d",s);
}