C语言中有许多基本的数据类型,如char,int,double等。
char是字符类型,可以保存一个字符,int是整数类型,可以保存一个整数,double是双精度实型,可以保存一个实数。例如:
char c = 'A';int i = 100;double pi = 3.14;
每个变量在定义的时候都会获得一个地址。前面小猫已经知道可以用&运算符获取一个变量的地址,变量的地址其实就是一个整数值,在64位系统上变量的地址有8个字节。那么,应该可以用一个long long型的数据来保存它。试一下看看:
#include #include int main(){ int b; long long i = &b; //用long long类型保存变量b的地址 printf("%X",i); system("pause"); return 0;}
运行结果如下:
输出了b的地址
说明变量b的地址确实可以保存在long long类型中,变量的地址本质上确实就是个整数。但小猫看到编译的时候,有一条警告信息: warning: initialization of 'long long int' from 'int *' makes integer from pointer without a cast [-Wint-conversion]。
gcc的警告信息
看来,虽然将地址赋值给long long类型,可以输出结果,但地址和long long类型还是有区别的。
在C语言里,地址要用一种特殊的变量来保存,叫做指针变量。指针变量是专门用来保存一个变量的地址的。不同类型的变量,需要保存在不同的指针变量中,例如int类型的数据,它的地址需要保存在专门保存int类型的指针变量中,指针变量的定义方式为:
int* p;//定义了一个用于存放int类型数据地址的指针变量char* p; //定义了一个用于存放char类型数据地址的指针变量
指针的定义与对应的类型定义相比,就是多了一个*号。那么,现在我们定义一个指针变量来接收b的地址,看看还有没有警告信息:
#include #include int main(){int b ;int* p = &b; //定义了一个int*类型的指针变量保存b的地址printf("%X",p);//输出p的值system("pause");return 0;}
输出结果与之前long long类型接收是一样的,但是警告信息没有了。
虽然如此,但小猫想,既然变量的地址本质上就是一个整数,那何必多此一举呢?而且不同的数据类型还要对应不同的指针类型,有必要吗?
其实指针变量与整型变量最大的不同在于对指针变量做加减法。如果我们让一个int类型的变量自增1,那么它就是加1。例如:
int b = 0;b++; //b的值为1
如果我们让一个指针变量自增1,那么它会加上相应数据类型所占用的字节数。具体来说,一个char*型指针变量,加1就是加1,因为char只占1个字节。而一个int*型指针加1,那么实际会加4,因为int占4个字节。这样的设计可以方便我们以若干个字节为单位在内存中移动,这也是为什么需要多种指针类型的原因。
写一小段代码,看看指针是不是这样工作的:
#include #include int main(){int b;int* p = &b; //p为int*类型指针printf("%X",p); //输出p的值p++; //指针自增1printf("%X",p); //输出p自增后的值,预期值会增加4system("pause");return 0;}
运行结果:
指针自增后运行结果
果然是这样。开心。
C语言学习日记