指针的概念
地址与指针
地址是内存中每个字节的编号,简单的理解指针就是一个内存地址,但是他是个变量,是可以改变的。
变量和指针
变量的地址是变量和指针二者链接的纽带。如果一个变量包含了另一个变量的地址则可以理解成第一个变量指向第二个变量。所以将一个变量的地址复制给一个指针变量后,
这个指针变量就指向了这个变量。
指针变量
一般形式
类型说明 * 变量名;
指针变量的赋值
未经赋值的指针变量不能使用,真真变量只能赋予地址,不能是其他数据。c语言中提供地址运算符来表示变量的地址。 即 &变量名
int a; int *p=&a; 或者 int a;int *p; p=&a;
强调:int *p; p=1002; 这个是错的
指针变领的引用
#include<stdio.h>
main( )
{
int *p,q;
printf("please input:\n");
scanf("%d",&q); /*输入一个整型数据*/
p = &q;
printf("the number is:\n");
printf("%d\n",*p); /*输出变量的值*/
}
&和*运算符
&是取地址运算符,单目运算符 p=&i; 返回操作数的地址
*是指针运算符,单目运算符 q=*p; 返回指定地址单元内的值
&和*的应用
#include<stdio.h>
main()
{
long i;
long *p;
printf("please input the number:\n");
scanf("%ld",&i);
p=&i;
printf("the result1 is: %ld\n",&*p); /*输出变量i的地址*/
printf("the result2 is: %ld\n",&i); /*输出变量I的地址*/
}
指针自加自减运算
指针的自加自减运算不同与普通变量的自加自减运算,以下两个实例简单说明
#include<stdio.h>
main()
{
int i;
int *p;
printf("please input the number:\n");
scanf("%d",&i);
p=&i; /*将变量i的地址赋给指针变量*/
printf("the result1 is: %d\n",p);
p++; /*地址加1,这里的1并不代表一个字节*/
printf("the result2 is: %d\n",p);
}
运行结果:
please input the number:
36
the result1 is:1245052
the result1 is:1245056
若改成
#include<stdio.h>
main()
{
short i;
short *p;
printf("please input the number:\n");
scanf("%d",&i);
p=&i; /*将变量i的地址赋给指针变量*/
printf("the result1 is: %d\n",p);
p++; /*地址加1,这里的1并不代表一个字节*/
printf("the result2 is: %d\n",p);
}
运行结果:
please input the number:
36
the result1 is:1245052
the result1 is:1245054
以上两例子说明指针的自增自减指的是变化一个数据类型的内存地址。
字符串与指针
访问一个字符串可以通过两种方式:①就是字符数组来存放一个字符串 ②就是字符指针指向一个字符串
#include<stdio.h>
main()
{
char *string="hello mingri";
printf("%s",string); /*输出字符串*/
}
指针数组
指针数组就是数组中的每一个元素都是指针变量。优点:节省内存空间
如下例输出12个月
#include<stdio.h>
main()
{
int i;
char *month[]=
{
"January",
"February",
"March",
"April",
"May",
"June",
"July",
"August",
"September",
"October",
"November",
"December"
}; /*给指针数组中的元素赋初值*/
for(i=0;i<12;i++)
printf("%s\n",month[i]); /*输出指针数组中的各元素*/
}
指向指针的指针
注意:*运算符自右向左结合
使用指向指针的指针输出12个月
#include<stdio.h>
main()
{
int i;
char **p;
char *month[]=
{
"January",
"February",
"March",
"April",
"May",
"June",
"July",
"August",
"September",
"October",
"November",
"December"
}; /*给指针数组中的元素赋初值*/
for(i=0;i<12;i++)
{
p=month+i;
printf("%s\n",*p); /*输出指针数组中的各元素*/
}
}
指针的指针输出一位数组中偶数的元素,并统计个数
#include<stdio.h>
main()
{
int a[10],*p1,**p2,i,n=0; /*定义数组、指针、变量等为基本整型*/
printf("please input:\n");
for(i=0;i<10;i++)
scanf("%d",&a[i]); /*给数组a中各元素赋值*/
p1=a; /*将数组a的首地址赋给p1*/
p2=&p1; /*将指针p1的地址赋给p2*/
printf("the array is:");
for(i=0;i<10;i++)
{
if(*(*p2+i)%2==0)
{
printf("%5d",*(*p2+i)); /*输出数组中的元素*/
n++;
}
}
printf("\n");
printf("the number is:%d\n",n);
}
指针变量做函数参数
指针变量作为函数的参数,相当于传引用,即实际参数同形参发生的变化
#include <stdio.h>
void swap(int *a,int *b)
{
int tmp;
tmp=*a;
*a=*b;
*b=tmp;
}
main()
{
int x,y;
int *p_x,*p_y;
printf("请输入两个数:\n");
scanf("%d",&x);
scanf("%d",&y);
p_x=&x;
p_y=&y;
swap(p_x,p_y);
printf("x=%d\n",x);
printf("y=%d\n",y);
}
输出结果:x,y互换
下例则为普通变量传递, 传值#include <stdio.h>
void swap(int a,int b)
{
int tmp;
tmp=a;
a=b;
b=tmp;
}
main()
{
int x,y;
printf("请输入两个数:\n");
scanf("%d",&x);
scanf("%d",&y);
swap(x,y);
printf("x=%d\n",x);
printf("y=%d\n",y);
}
输出结果:x,y不变
编程实现对12个月份按字母排序
#include <stdio.h>
#include <string.h>
sort(char *strings[], int n) /*自定义排序函数*/
{
char *temp;
int i, j;
for (i = 0; i < n; i++)
{
for (j = i + 1; j < n; j++)
{
if (strcmp(strings[i], strings[j]) > 0) /*比较两个字符串的大小*/
{
temp = strings[i];
strings[i] = strings[j];
strings[j] = temp; /*如果前面字符串比后面的大,则互换*/
}
}
}
}
main()
{
int n = 12;
int i;
char **p; /*定义字符型指向指针的指针*/
char *month[] =
{
"January",
"February",
"March",
"April",
"May",
"June",
"July",
"August",
"September",
"October",
"November",
"December"
};
p = month;
sort(p, n); /*调用排序函数*/
printf("排序后的12月份如下:\n");
for (i = 0; i < n; i++)
printf("%s\n", month[i]); /*输出排序后的字符串*/
}
返回指针值的函数
求矩形周长
#include <stdio.h>
int per(int a,int b);
void main()
{
int iWidth,iLength,iResult;
printf("请输入长方形的长:\n");
scanf("%d",&iLength);
printf("请输入长方形的宽:\n");
scanf("%d",&iWidth);
iResult=per(iWidth,iLength);
printf("长方形的周长是:");
printf("%d\n",iResult);
}
int per(int a,int b)
{
return (a+b)*2;
}