指针就是地址!
概念
C语言中,允许用一个变量来存放地址,这种变量称为指针变量。一个指针变量的值就是某个内存单元的地址。指针变量就是用来存放指针(地址)的变量!
&运算符:求某一变量在存储单元中的内存地址。
*运算符:取出指针变量所指向变量的内容,后面跟指针变量。
目的
定义指针的目的就是为了通过指针去访问存储单元。
指针变量的定义
一般形式: 类型标识符 *指针变量名
指针变量名前面的*号表示该变量为指针变量,它不是变量名本身的一部分。
指针变量的类型标识符一定要与指针变量指向的地址中存放的数值类型一致。
例如
1.先定义再指向
int a=10;
int *p;
p=&a; //p中保存了a 的地址值,称指针变量p指向了变量a
指针变量p的类型标识符(int)与a中保存的数值10对应的类型标识符(int)一致
2.定义指针变量的同时,让指针变量有所指(指向变量a)
//下面这种定义同上面是一样的
int a=10;
int *p=&a;
指针变量的使用
1.指针变量是一个变量,它在内存中也会有一个内存地址,因此其他的指针变量也可以指向这个指针变量(其他的指针变量可以保存该指针变量的地址值)
int a=10;
int *p=&a; 指针变量p指向了变量a(指针变量p有所指)
int **q=&p;
//int **q=&p代码解释
&p:取出指针变量p的地址值
int **q 相当于 int *(*q):
1.括号里的*表示q是一个指针变量
2.外面的int * 表示指针变量q指向的变量的类型是一个整型(int)的指针变量
2.指针变量内只能存放其他变量的地址值,而不能直接存放一个普通的数据
int *a = 10086; /*错误*/
int *b = 0; /*正确:可以赋值0,但这个指针变量不指向任何具体的变量*/
int *c = 0x00002000;/*错误*/编译器并不知道这个数据是一个地址值,因为你没有告诉它
int *d = (int *)0x00002000;/*正确*/将0x00002000转换为int类型指针(int类型地址)
使用的前提是你确定这个内存确实可以使用,不然对该地址的内容进行操作时, 会出现引用非法指针的错误,导致程序崩溃。
怎么告诉编译器这个数据是一个地址值呢?
1.使用&运算符,但&运算符只能取一个变量的内存地址,它取不了一个常数的内存地址,所以只能使用2方法
2.将这个数据强制类型转换为某个数据类型的指针
指针与字符串
char *string="hello"; //指针变量string保存的是字符串的首地址
printf("%s",string);
打印结果:hello
输出指针变量的写法是string,而不是*string!
char *string="hello"; //指针变量string保存的是字符串的首地址
printf("%s",(void*)string);
打印结果:"hello"的地址值
将string强制转化为void指针类型,就可以输出地址值,而不是数据值
当输出字符类型的指针时,这个指针显示的是该指针所指向的数据内容,而不是该数据的地址。一定要注意,只有字符类型的指针才会这样,其他类型的指针显示的是地址,而不是数据。
原因:C格式的字符串是通过字符的指针定义的。
例子:
int a[3]={1,2,3};
int *string = a;
printf("%s\n",string);
printf("%S\n",*string);
打印结果:
数组a的内存地址
1
强调:只有指向字符类型的指针变量才能使用printf("%s",string)输出数据,而不是地址值
指针数组
若一个数组的元素类型为指针,则称该数组为指针数组(数组中所有元素保存的都是地址值)
char *string[]={
"张三",
"李四",
"王五"
};
printf("%s\n",string[0]);
printf("%s\n",string[1]);
printf("%s\n",string+[2]);
打印结果:
张三
李四
王五
理解:string是一个字符串数组,string[0]保存的是"张三"的地址值,因为它是字符型的指针变量,
所以可以直接使用printf("%s\n",string[0])输出数据,而不是地址
请参考指针与字符串