C语言程序设计 指针C语言学习
重点:
1、C语言中指针的概念
2、指针变量的相关操作
3、指针与数组的关系
4、内存空间的动态分配
第1节 C语言中指针
一、指针与指针变量
一台计算机的内存单元非常多,为了相互区分,就给它们采取编号的方法,按十进来说,从0开始编号,即0,1,2……,这种对每个内存单元的唯一的编号叫做内存单元的地址。计算机对内存的访问一般采取“按地址访问”的方式。
变量(指前面所讲的普通变量)的实质对应的是内存单元,对变量的操作实质是对相应内存单元中所存放的数据的操作:给变量赋一个值,实质是将一个值存入与此变量对应的内存单元;读取一个变量的值,实质是从对应的内存单元中取出存放的数据。
有时,我们要用到内存单元的地址,这种情况下,可利用C语言中的“指针”数据类型来实现。
指针就是变量的地址,实质是内存单元的地址。
可以用变量来存放指针,称为指针变量,但跟普通变量不同的是,普通变量存放数据,指针变量存放的是变量的地址,即内存单元的地址。
1、指针变量的定义
数据类型符 *变量名;
如:
int *a,*b;
float *fp;
2、指针变量的赋值
1)初始化赋值
数据类型 *指针名=初始地址值;
例:
int x=20;//定义了一个普通的整型变量
int *p=&x; //定义了一个指向整型变量的指针变量,并让p指向变量x所对应的内存单元,即p中存入x所对应的内存单元的地址。如下图:
例:
int i;
int *p = &i;
int *q = p;
2)赋值语句赋值
int a;
int *p;
p = &a;
3、与指针相关的运算符
&:取地址运算符,获得变量的地址
*:访问指针所指变量内容的运算符
上例中,要获得内存单元10000中的内容有两种办法:
①直接访问:按变量名来存取变量值。上例中可通过x来实现;
②间接访问:通过存放变量地址的指针变量去访问。上例中可通过*p访问。
注意:p代表地址而*p代表内容。
例:
输入两个数,并使其从大到小顺序输出,用指针实现。
#include <stdio.h>
void main( )
{
int a,b,*p1,*p2,*p;
printf("\n请输入两个整数:");
scanf ("%d%d",&a,&b);
p1=&a;
p2=&b;
if(*p1<*p2)
{
p=p1;p1=p2;p2=p;
}
printf("a=%d,b=%d\n",a,b);
printf("max=%d,min=%d\n",*p1,*p2);
}
说明:
1、指针变量必须先定义,后赋值,最后才能使用!没有赋值的指针变量是没有任何意义的,也绝对是不允许使用的。如下例:
#include "stdio.h"
void main( )
{
int *p1,*p2;
printf("\n请输入两个整数:");
scanf ("%d%d",p1,p2);
printf("max=%d,min=%d\n",*p1,*p2);
}
例中的指针变量p1和p2没有赋值,使用时就会出错。
2、指针变量只能指向定义时所规定类型的变量。如果给指针赋值时,=号右边的指针类型与左边的指针类型不同,则需要进行类型强制转换。
例:
int a;
int *pi;
char *pc;
pi=&a;//pi指向a
pc=(char*)pi;//pc也指向了a,即pi和pc的值都是a的地址
3、普通变量随着类型的不同,在内存中所分配的内存单元可能也会发生变化。指针变量也是变量,在内存中也要占用一定的内存单元,但所有类型的指针变量都占用同样大小的内存单元,其具体大小取决于所使用的编译环境,如在VC6.0下为4个字节,在TC2.0下为2个字节。
二、指针和地址运算
1、指针变量的加、减运算
指针可以参与加、减运算,但其加、减的含义不同于一般数值的加减运算。如下例:
#include "stdio.h"
void main()
{
int *pi;
char *pc;
pi=(int *)1000;
printf("\npi=%d",pi);
pc=(char *)1000;
printf("\npc=%d",pc);
pi++;//pi的值将是1004 (假设int型占4B)
printf("\npi=%d",pi);
pi-=2;//pi的值将是996
printf("\npi=%d",pi);
pc++;//pc的值将是1001
printf("\npc=%d",pc);
pc-=2;//pc的值将是999
printf("\npc=%d",pc);
}
如果指针p是这样定义的:
ptype *p;
并且p当前的值是ADDR,那么:
p±n 的值=ADDR±n*sizeof(ptype)
即指针加上或减去一个整数相当于将指针以定义时所用的数据类型占用内存的字节数为单位向后或向前移动n个单位。
两个指针相加没有任何意义,但两个指针相减则有一定的意义,可表示两指针之间所相差的内存单元数或元素的个数,在后面的学习中就会体会到。
2、指针变量的关系运算
若p1和p2指向同一类型的变量,则
p1<p2 表示p1所指的单元在p2之前
p1>p2 表示p1所指的单元在p2之后
p1==p2 表示p1与p2指向共同的单元
若p1与p2指向的是同一数组中的元素(变量),则上述比较有意义,否则比较没有实际意义
第2节 指针与数组的关系
一、数组的指针与指向数组的指针变量
1、数组的指针:其实就是数组在内存中的起始地址。而数组在内存中的起始地址就是数组变量名,也就是数组第一个元素(下标为0)在内存中的地址。如下图:
p + 1指向数组的下一个元素,而不是简单地使指针变量p的值+1。其实际变化为p+1*size(size为一个元素占用的字节数)。
2、指向数组的指针变量:如果将数组的起始地址赋给某个指针变量,那么该指针变量就是指向数组的指针变量。如上图:
下面是对数组元素赋值的几种方法,它们从功能上是等价的:
方法一:
char str[10];
int k;
for(k=0;k<10;k++)
str[k]='A'+k; //也可写成*(str+k)='A'+k方法二:
char str[10],*p;
int k;
p=str;
for(k=0;k<10;k++)
p[k]='A'+k; //也可写成*(p+k)='A'+k
方法三:
char str[10],*p;
int k;
p=str;
for(k=0;k<10;k++)
*p++='A'+k; //相当于 *p='A'+k; p++;
注意:数组名是地址常量,切不可对其赋值,也不可做++或--运算。例如:int a[10];如果在程序中出现a++或a--则是错误的。
下面一个例子用来说明数组元素的各种不同引用方法:
#include <stdio.h>
void main( )
{ int a[2],*pa,i;
for(i=0;i<2;i++)
a[i]=i+1;
pa=a;
for(i=0;i<2;i++)
printf("*(pa+%d):%d\n",i,*(pa+i));
for(i=0;i<2;i++)
printf("*(a+%d):%d\n",i,*(a+i));
for(i=0;i<2;i++)
printf("pa[%d]:%d\n",i,pa[i]);
for(i=0;i<2;i++)
printf("a[%d]:%d\n",i,a[i]);
}
例:设有如下定义:int a[]={1,2,3,4,5,6,7,8,9,10},*p=a,i;
下列对数组元素地址的正确表示是:
(A)&(a+1) (B)a++ (C)&p (D)&p[i]
二、二维数组与指针的关系
二维数组可看作是特殊的一维数组:其每个元素本身就是一个一维数组。C语言中的二维数组在内存中是按“行序优先”的方式排列。
看下例:
#include <stdlib.h>
#include <stdio.h>
c语言指针实验总结void main()
{
int a[2][3]={{1,2,3},{4,5,6}};
int i,j,*p;
p=&a[0][0];
for(i=0;i<2;i++)
{
for(j=0;j<3;j++)
printf("%8d%8d",p,*p++);
printf("\n");
}
system("pause");
}
运行结果如下:
第3节 指针与字符串
用C语言表示字符串时有如下两种形式:
一、用字符数组实现
例:
#include <stdio.h>
void main ( )
{ char string[] = "I love China!";
printf ("%s\n", string);
printf ("%s\n", string + 7);
}
二、用字符指针实现
例:
#include <stdio.h>
void main ( )
{
char *string = "I love China!";
printf("%s\n", string);
string+=7;
puts(string);
}
#include <stdio.h>
void main ( )
{
char *string = "I love China!";
printf("%s\n", string);
string+=7;
while(*string)
{
putchar(string[0]);//也可以写成putchar(*string);
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论