0 指针的基础知识
0.1 指针的概念
指针变量:指针变量也是一个变量,在指针中存放的内容是一块内存空间的地址。就是说,指针就是
内存地址:计算机内存的最小单位是Byte,每一个Byte都有一个唯一的编号,这个编号就是内存空间的地址,通常叫作内存地址。这个编号在32位操作系统下是一个32位的整数,在64位操作系统下是一个64位的整数。
例如在win64系统下的VS2015中运行一下程序:
#include<stdio.h> int main() { int a ; int b = 100000000; printf("a的地址是:%p\n", &a);//&a就是取a的地址 printf("b的地址是:%p\n", &b); return 0; }
运行结果是:
0.2 指针变量的定义
指针变量定义的语法:int *p = &a; 其中:“*” 解引用,“&” 取地址。p指针,*p代表指针指向的那个变量,其实就是a。如果单独输出p,就是变量的a的地址。
看下面的例子:
#include<stdio.h> int main() { int a ; int b = 100000000; printf("a的地址是:%p\n", &a); printf("b的地址是:%p\n", &b); int *p = &a;//得到变量a的地址,将这个地址赋值给变量p printf("p是:%x\n", p); return 0; }
运行结果是:
这里要注意一下,指针变量定义的时候,有可能读者会出现这样的疑惑:
int a=10; int *p; *p=&a;
上面的写法是错的,&a是变量a的地址,不能赋值给野指针*p,正确的写法通常有以下两种:
int a=10; int *p; p=&a;
也可以简化写成:
int a=10; int*p=&a;
以下四点需要注意下:
1)地址虽然是一个整数,但地址是一个特殊的整数,是不能直接通过整数操作进行的,虽然一下两句是等效的:
int *p=&a; int p=&a;
2) int *p的意义:定义一个变量,名字叫p,它可以指向一个int类型变量的地址。在之后利用p,
int a; int *p; p=&a;//指针变量的值一般不能直接赋值一个整数,而是通过取变量地址的形式赋值p1=10;//不能这样为指针赋值
3)*P的意义:指针变量指向的内存空间的内容。示例程序:
#include<stdio.h> int main() { int a = 10; int *p = &a; int b; b = *p;//指针变量指向的内存空间的内容 printf("p是:%d\n", b); return 0; }
运行结果:
4)通过指针间接修改指针变量指向变量的值
int a=10; int *p=&a; *p=20; printf("a的值是:%d\n",a);
运行结果是:
1 指向常量的指针与常量指针
指向常量的指针与指针常量的定义:
const int *p;//定义一个指向常量的指针 int *const p;//定义一个常量指针,一旦初始化,就不能修改其指向
1.1 指向常量的指针
指向常量的指针只能指向一个常量,例如:
int a =10; const int *p = &a;//p这个指针只能指向一个常量 *p = 20;//不能通过*p的方法修改一个const指针,此时*p是只读的
可以这样用:
int a =10; int b =20; const int *p = &a;//p这个指针只能指向一个常量 p = &b;//此时*p打印出来是20
1.2 常量指针
常量指针一旦被定义,不能修改其指向,例如
int a =10; int b =20; int *const p = &a; p = &b;//错误,一旦定义了常量指针,就不能修改指针的指向,从一而终,相当于古代的好女人
2 数组的指针
先看示例程序:
#include<stdio.h> int main() { char buf[10]; printf("%u, %u, %u, %u\n", buf, &buf[0], &buf[1], &buf[2]); return 0; }
运行结果:
可以看出,数组中,buf就是取数组的首地址,与&buf[0]等效。
数组的指针的示例程序:计算字符串长度#include<stdio.h> int main() { char s1[] = "hellow"; char s2[] = "world"; char *p = s1; int length = 0; while (*p)//*pd的内容为0时,跳出循环 { p++; length++; } printf("s1长度:%d\n", length); return 0; }
运行结果:
数组的指针的示例程序:实现两个字符串相加
#include<stdio.h> int main() { char s1[20] = "hellow"; char s2[20] = "world"; char *p1 = s1; int length = 0; while (*p1) { p1++; length++; } char *p2 = s2; while (*p2) { *p1 = *p2;//注意此时*p1在字符串s1的末尾,直接将*p2接上了 p2++; p1++; } printf("s1长度:%d\n", length); printf("s1=%s\n", s1); return 0; }
运行结果:
3 指向指针的指针(二级指针)
指针的其实是一个变量,既然是变量,同样也存在地址,所以可以定义一个指向指针的指针。例如:
int a=10; int *p=&a; int **pp=&p;//定义了一个二级指针,指向了一个一级指针的地址