指针就是地址,指针变量就是存储地址的变量
指针变量定义形式:类型名 *指针变量名;
int main()
{
int a=10;
int *p=&a; //指针p指向a
printf("%d\n",&p); //取地址符号,表示输出的是地址,结果为a的地址,也就是p指向的地址
printf("%d\n",p); //对然没有取地址符,但是指针本身就是地址,所以输出地址
printf("%d\n",*p); //指针变量,当然输出指针p所指向地址里面的内容,也就是a的值
*p=100; //指针变量p改变,它所指向地址的值也回改变,也就是a的值会发生改变
printf("%d\n",a);
return 0;
}
空指针:指针指向为空,也就是给指针变量赋值为NULL。可以防止我们因任意赋值而带来的错误。
万能指针
int main()
{
void *p = NULL; //万能指针的定义
int a =10;
p=&a;
printf("%d\n",*(int *)p);//想要操作万能指针时,需要先强制类型转换,让他成为一个特定的指针
return 0;
}
const修饰的指针:
int main()
{
int a = 10;
int b = 12;
//第一种:const修饰*,指针变量是可写的,但是指针变量所指向的内存空间是只读的。
const int *p1 = &a;
*p1=100; //表示我们指针所指向的内存是只读的。
//这样就可以
p1 = NULL;
p1 = &b;
//第二种:const修饰指针变量,指针变量就是只读的,但是指针变量所指向的内存空间是可写的。
int * const p2 = &a;
*p2 = 1000;
return 0;
}
多级指针:
int main()
{
int a = 10;
int *p = &a; //p是一级指针,指向a
int **q = &p; //*q代表p,**q代表*p
return 0;
}
通过指针操作数组元素
int mian()
{
int a[5] = {1,2,3,4,5};
int *p = NULL;
int *q[3];
int i,j;
p = &a[0]; //使指针变量p指向数组a的首元素。
p = a; //将数组名直接赋值给p,这里可以这样操作的原因是:数组名代表的是此数组第一个元素的地址!!
//输出数组中数据的几种方法
for(i=0;i<5;i++)
{
printf("%d ",a[i]); //数组名+下标
printf("%d ",*(p+i)); //指针表示方法
printf("%d ",p[i]); //因为p指针和a指针等效
//这个的效果和上面三个一样
printf("%d ",*p);
p++;
}
//操作指针数组
for(j=0;j<3;j++)
{
q[j] = &a[j];
}
return 0;
}
字符指针:
int mian()
{
char str[] = "hello";
char *p = NULL; //定义字符指针
p = &str[0];
*p = 'a';
p++;
*p = 'b';
printf("%s\n",str); //输出abllo
printf("%s\n",p); //输出bllo
return 0;
}
字符指针作为函数参数的用法:
void my_strcpy(char *a,char *b)
{
int i = 0;
while(*(b+i)!='\0')
{
*(a+i) = *(b+i);
i++;
}
*(a+i) = '\0';
}
int main()
{
char src[] = "hello world";
char des[] = "China";
my_strcpy(src,des);
printf("%s\n",src);
return 0;
}
const修饰指针和指针变量
int main()
{
char str[] = "hello";
const char *p = str;
char * const p1 = str;
*p = 'b'; //这里会报错,因为const修饰指针,指针所指向的内容是只读的,即不可以修改
p = NULL; //使用const修饰指针,指针变量本省是可以修改的
*p1 = 'b'; //这里没错,指针变量所指向的内容是可以修改的
p1 = NULL; //这里就会报错,因为const修饰指针变量,指针变量本身是只读的,不可修改
return 0;
}