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;}

运行结果如下:




targetNamespace_c++ 智能指针

输出了b的地址



说明变量b的地址确实可以保存在long long类型中,变量的地址本质上确实就是个整数。但小猫看到编译的时候,有一条警告信息: warning: initialization of 'long long int' from 'int *' makes integer from pointer without a cast [-Wint-conversion]。




targetNamespace_c语言 char转int_02

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;}

运行结果:




targetNamespace_c++ 智能指针_03

指针自增后运行结果



果然是这样。开心。




targetNamespace_c++ 智能指针_04

C语言学习日记