指针是C语言中的一个重要的概念及其特点,是掌握C语言比较困难的部分。指针就是内存地址,指针变量是用来存放内存地址的变量。
一.指针变量
1.定义带“ * ”类型的变量:
char x; | char* x; |
---|---|
short y; | short* y; |
int z; | int* z; |
float f; | float* f; |
double d; | double* d; |
Student st; | Student* st; |
总结:
1.带有星号的变量类型的标准写法:变量类型* 变量名。
2.任何类型都可以带星号,加上星号以后是新的类型,统称“指针类型”。
3.星号可以是一个或多个。
2.指针变量赋值:
#include <stdio.h>
int main( int argc,char * agrv[ ])
{
char* x;
int* y;
x= (char*)1;
y= (int*)2;
return 0;
}
3.指针类型的宽度:
#include <stdio.h>
struct Point
{
int x;
int y;
};
int main(int argc,char * agrv[ ])
{
char* x; //char 1
int* y; //int 4
Point* point; //point 8
x= (char*)1;
y= (int*)2;
Point= (point*)0;
printf("%d %d %d \n",sizeof(x),sizeof(y),sizeof(point));
return o;
}
总结:指针类型的变量宽度永远是4字节
4.指针类型自加和自减(++ / --):
char a; | char* a; |
---|---|
short b; | short* b |
int c; | int* c; |
a=100 | a= (char*)100; |
b=100 | b= (short*)100; |
c=100 | c= (int*)100; |
a++; | a++; |
b++; | b++; |
c++; | c++; |
printf("%d %d %d",a,b,c); | printf("%d %d %d",a,b,c); |
#include <stdio.h>
strust Point
{
int x;
int y;
};
int main(int argc,char*agrv[ ])
{
char* a;
short* b;
int* c;
Point* d;
a= (char*)100;
b= (short*)100;
c= (int*)100;
d= (Point*)100;
a++; //char* - * =char =1
b++; //short* - * =short =2
c++; //int* - * = int =4
d++; //Point* - * =Point =8
printf("%d %d %d %d \n",a,b,c,d);
return 0;
}
总结:
1.不带*类型的变量,++或-- 都是加1或者减1
2.带星号类型的变量,++或者-- 新增(减少)的数量是去掉一个星号后变量的宽度。
5.指针类型的加减运算:
char* a; |
---|
short* b; |
int* c; |
a= (char*)100; |
b= (short*)100; |
c= (int*)100; |
a=a+5; |
b=b+5; |
c=c+5; |
printf("%d %d %d",a,b,c); |
#include <stdio>
strust Point
{
int x;
int y;
};
int main(int argc,char*agrv[ ])
{
char* a;
short* b;
int* c;
Point* d;
a= (char*)100;
b= (short*)100;
c= (int*)100;
d= (Point*)100;
a=a+5; //5*(char* - *) 5
b=b+5; //5*(short* - *) 10
c=c+5; //5*(int* -*) 20
d=d+5; //5*(Point* - *) 40
printf("%d %d %d %d",a,b,c,d);
return 0;
}
总结:
1.指针类型的变量可以加、减一个整数,但不能乘或除。
2.指针类型变量与其他整数相加或相减时:
指针类型变量+N = 指针类型变量 +N*(去掉一个*后类型的宽度);
指针类型变量-N = 指针类型变量 -N星(去掉一个星后类型的宽度)
二.指针
取地址运算
运算符:&
- scanf( “%d”, &i );里的&
- 获得变量的地址,它的操作数必须是变量
- int i;printf (“%x”,&i );
- 地址的大小是否与int相同取决于编译器
- int i;printf("%p",&i);
#include <stdio.h>
struct Point{
int x;
int y;
};
int main(int argc,char*agrv[ ])
{
char a=0;
short b=1;
int c=2;
Point p={3,3}
printf("%d \n",&a);
return 0;
}
&不能取的地址:
&不能对没有地址的东西取地址-&( a+b)、&(a++)
指针:就是保存地址的变量
int i;
int* p=&i;
int* p,q;
int *p,q;
指针变量
- 变量的值是内存的地址
- 普通变量的值是实际的值
- 指针变量的值是具有实际值的变量的地址
作为参数的指针
- void f(int *p);
- 在被调用的时候得到了某个变量的地址;
- int i=0;f(&i);
- 在函数里面可以通过这个指针访问外面的这个i
访问那个地址上的变量*
- *是一个单目运算符,用来访问指针的值所表示的地址上的变量
- 可以做右值也可以做左值
- int k =*p;
- *p = k+1;
指针应用场景
交换两个变量的值
void swap(int *pa,int *pb)
{
int t = *pa;
*pa = *pb;
*pb = t;
}
指针最常见的错误
定义了指针变量,还没有指向任何变量,就开始使用指针
指针与数组
int isPrime(int x,int knownPrimes[ ], int numberOfKnownPrimes)
{
int ret = 1;
int i;
for ( i=o;i<numberOfKnownPrimes;i++ ) {
if (x % KnownPrimes[i] ==0 ) {
ret = 0;
break;
}
}
return ret;
}
- 函数参数列表中的数组实际上是指针
- sizeof(a) == sizeof(int*)
- 但是可以用数组的运算符[ ]进行计算
数组参数
以下四种函数原型是等价的:
- int sum(int *ar,int n);
- int sum(int *,int);
- int sum(int ar[ ],int n);
- int sum(int [ ],int);
数组变量是特殊的指针
- 数组本身表达地址,所以,int a[10];int*p=a; //无需用&取地址,但数组的单元表达的是变量,需要取地址
- [ ]运算符可以对数组做,也可以对指针做:p[0]<==>a[0]
- *运算符可以对指针做,也可以对数组做:
- *a=25
- 数组变量是const指针,所以不能被赋值