指针的概念
指针:指针变量是一个变量(整数),指针存放的内容是一个地址,该地址指向一块内存空间。
内存:
计算机内存最小单位是byte(字节),每一个字节的内存都有一个唯一的编号,这个编号就是内存的地址,编号在32位系统下一个32位的整数,在64位系统下是64位的整数
#include <stdio.h>
int main(){
int a=0;
char buf[10];
printf("%p,%p\n",&a,&buf);//取变量地址的意思
return 0;
}
/Users/Xx/CLionProjects/Struct1/cmake-build-debug/Struct1
0x7ffee1f30b04,0x7ffee1f30b0e
Process finished with exit code 0
0x7ffee1f30b04
这里的1个数字就是一个字节,在int
类型下,p+1
操作,其实是0x7ffee1f30b04+4
,移动了一个int的内存大小。
指针的定义:
#include <stdio.h>
int main(int argc,char *argv[]){
int a=1;
int b=2;
int *p1=&a;
//int *p1;
//p1=&a;
int *p2=&b;
int temp;
temp=*p1;
*p1=*p2;
*p2=temp;
printf("变量为地址:%d,%d\n",p1,p2);
printf("--------------\n");
printf("变量为数值:%d,%d\n",*p1,*p2);
return 0;
}
变量为地址:6618632,6618628
--------------
变量为数值:2,1
Process finished with exit code 0
int *p=&a;
得到变量a的地址,将这个地址赋值给变量p
int p=&a;
地址虽然是个整数,地址是个特殊的整数。是不能通过整数来操作的。
int *p1;
定义一个指针变量,名字叫p1,它可以指向一个int类型的地址。
&p
取地址,取出变量p的地址
*p
取值,指针变量指向内存的内容
区分:int *p=&a;
= int *p;p=&a;
*p=100 | 将100赋值给指针p指向的内存(内容) |
---|---|
p=100 | 将整数100赋值给变量p(地址),这里是野指针 |
#include<stdio.h>
int main(){
int buf[10];
printf("%u,%u,%u\n",&buf,&buf[1],&buf[2]);
printf("-----------------------\n");
char buf1[10];
printf("%u,%u,%u",&buf1,&buf1[1],&buf1[2]);
return 0;
}
D:\SystemP\bulingbuling\Clion\Prog\cmake-build-debug\Prog.exe
6618608,6618612,6618616
-----------------------
6618598,6618599,6618600
Process finished with exit code 0
数组名字代表数组第一个元素。char类型的数据,其中两两相邻的相差1个字节,与之对应的int类型,两两相差4个字节。
无类型指针:
void *p1;
无类型指针,意思是这里只是一个指针,而不指向任何具体的数据类型。
#include <stdio.h>
int main(){
int a1=0;
int *p1=&a1;
char a2=0;
char *p2=&a2;
printf("%d\n", sizeof(p1));
printf("%d\n", sizeof(p2));
return 0;
}
/Users/Xx/CLionProjects/Struct1/cmake-build-debug/Struct1
8
8
Process finished with exit code 0
这里的两个指针的字节数都是为8?
因为:指针本身就是一个地址,32位系统下4字节,64位系统下8字节。
NULL
p3=NULL;将指针赋值NULL,值为NULL的指针->空指针
空指针与野指针:
指向NULL的指针叫空指针,没有具体指向任何变量地址的指针叫野指针。
#include <stdio.h>
int main(){
int a=0;
int *p;
//p=&a;
*p=1;
printf("a=%d\n",*p);
return 0;
}
这里的p我们没有赋值给它,它没有指向的地址。对于int *p
来说是个未知的值。这里的指针p就是个野指针。程序中要避免野指针的存在,因为野指针是导致程序崩溃的主要原因。
指针的兼容性
#include <stdio.h>
int main(int argc,char *argv[]){
int a=2;
int b=3;
int c=4;
int *p;
p=&a;
*p=10;
p=&b;
*p=20;
p=&c;
*p=30;
printf("a=%d,b=%d,c=%d\n",a,b,c);
return 0;
}
a=10,b=20,c=30
Process finished with exit code 0
指针之间赋值比普通数据类型赋值检查更为严格,不可以把一个double
赋值给int
。
原则上一定是相同类型的指针指向相同的类型的变量地址,不能用一种类型的指针指向宁一种类型的变量地址。
#include <stdio.h>
int main(int argc,char *argv[]){
int a=0x1234;
char *p= reinterpret_cast<char *>(&a);//数据丢失
printf("%x",*p);
return 0;
}
34
Process finished with exit code 0
这里我们看见的输出为34,由于存储在x86下为小端存储,0x1234在char
存储的是一个字节中只能读取到34
指向常量的指针与指针变量
指向常量的指针:
#include <stdio.h>
int main(){
int a=10;
int b