C语言中关于指针介绍以及使用
一:指针的介绍
1:指针变量
- 地址变量(指针变量):存储地址
- 内容变量(普通变量):存放数据
2:指针变量的引用
&与*互逆 ,都是二级单目运算符 运算顺序:自右向左
-
“&” 运算符(功能:可以取出普通变量的地址)
-
“*” 运算符( 功能:取出指针变量所指向普通变量的值)
二:指针的使用
1:利用c语言中的自定义函数实现对main函数值的该变
实现思路:
- 向自定义1函数传入地址值
- 在修改是有*指针的运算
指针利用函数实现数据的交换
#include <stdio.h>
void swap1(int *p1,int *p2 ){
int temp;
temp=*p1;
*p1=*p2;
*p2=temp;
}
void swap2(int *p1,int *p2 ){
int c=10;
int *temp =&c;
*temp=*p1;
*p1=*p2;
*p2=*temp;
}
int main(){
int a=2,b=5;
int *p1=&a,*p2=&b;
// swap1(p1,p2);
swap2(p1,p2);
printf("%d %d\n",*p1,*p2);
return 0;
}
2:指向字符串的指针变量
由于C语言总没有字符串变量,因此字符串的实现借助了以下两种方式:
- char str[]=“people”; //借助字符数组实现
- char *p=“people”; //借助字符类型的指针实现
字符串本身就是一个字符地址,字符串的首地址(是一个字符常量)
3:指向一维数组的指针变量
- 在c语言中,数组名代表数组的首地址(改地址是一个地址常量)
- 当指针变量指向数组中的一个元素的时候,指针变量加1后指向数组的下一个元素,指针变量减1指向数组的前一个元素
- 当量两个指针指向同一个数组的时候,两指针可以进行大小的比较(比较的值为两指针指向数据间相差元素的个数)
例如利用指针来操作数组的实现
#include <stdio.h>
int main(){
int aa[]={1,2,3,4,5,6};
int *p,i;
int *q;
for ( p = aa; p<aa+6 ; ) //p = aa等价于&aa[0]
printf("%d ",*p++);
printf("\n");
p= &aa[2];//指向数组的第3个元素
q= (aa + 5);//指向数组的第6个元素
printf("%d",q-p);//相差的个数为3
return 0;
}
4:指向多维数组的指针变量
int a[3][4]
-
a+i是行指针,即指向的是一整行。若对它加1,则执行那个下一行
-
*(a+i)和a[i]一样都是一个列指针即指向的是一个元素
-
*(a+i)+j和a[i]+j一样都表示元素a[i][j]的地址
-
((a+i)+j)— (a[i]+j)—((a+i))[j]—a[i][j]表示具体的元素值
地址三等价 -
*(a+i)
-
a[i]+j
-
a[i][j]
元素四等价
- ((a+i)+j)
- *(a[i]+j)
- (*(a+i))[j]
- a[i][j]
a:列指针变量
列指针:指的是一行中某个具体元素。
列指针的使用,它就是把一个二维的数据转变层了一个一维数组与指针的使用
#include <stdio.h>
int main(){
int a[3][4]={1,2,3,4,5,6,7,8,9,10,11,12};
int *p=&a[0][3];
for (int i = 0; i <3 ; ++i) {
printf("%d ",*p=*(p=p+2));//循环打印三个元素,其中元素之间的间隔是2
}
return 0;
}
b:行指针变量
行指针:指的是一整行,不指向具体元素。
格式:
基类型 (*指针变量) [m]; ------(m是二维数组的列数)
利用指针打印数组中的元素
#include <stdio.h>
int main(){
int a[3][4]={1,2,3,4,5,6,7,8,9,10,11,12};
int (*p)[4];
p=a;
for (int i = 0; i < 3; ++i) {
for (int j = 0; j < 4; ++j) {
printf("%d ",p[i][j]);//其中a[i][j]等价于p[i][j];
}
printf("\n");
}
return 0;
}
5、指向函数的指针变量
函数名与数组名一样,是起始地址,而且是一个地址常量。
定义函数的指针变量的方式:类型名 (*指针变量名)();
#include <stdio.h>
int add(int x,int y){
x=10;
y=10;
return x+y;
}
int main()
{
int (*p)();
p=add;
printf("%d",(*p)());
}
6、返回指针的函数
其中函数名之前加了"*"号表明这是一个指针型函数,即返回值是一个指针。
格式:类型名 *函数名(形参){ return 一个地址;}
int *add(int x,int y){
x=x+y;
int *p=&x;
return p;
}
int main()
{
int *p;
p= add(10,20);
printf("%d",*p);
}
7、指针数组
指针数组:一个数组的所有元素均为指针类型
格式:类型名 *数组名[常量表达式];
#include "stdio.h"
int main(){
char a[3][4]={"123","456","789"};//少则为\0
char *p[3];
for (int i = 0; i <3 ; ++i) {
p[i]=a[i];//a[i]是一个列地址
}
for (int i = 0; i < 3; ++i) {
printf("%s \n",p[i]);
}
}
8、指向指针的指针变量
定义:用来存放指针变量地址的指针变量
格式:基类型名 **指针变量名;
#include "stdio.h"
int main(){
int a=2;
int *p=&a;
int **k=&p;
printf("a=%d\n",a);
printf("p指针指向%d\n",*p);
printf("k指针指向%d\n",**k);
}
三:遇到的主要问题
1:指针在没有指定初始指向地址时,导致程序的报错
错误信息: Process finished with exit code -1073741819 (0xC0000005)
解决思路:为当前指针指定一个地址。(具体情况具体看待)
#include <stdio.h>
void swap2(int *p1,int *p2 ){
int c=10;
//这里出现的问题
int *temp =&c;
//int *temp; 原来的定义指针未指定内存地址
*temp=*p1;
*p1=*p2;
*p2=*temp;
}
int main(){
int a=2,b=5;
int *p1=&a,*p2=&b;
swap2(p1,p2);
printf("%d %d\n",*p1,*p2);
return 0;
}