标签归档:pointer

C语言指针理解

最近在做OpenCL的项目,做异构计算。在做的过程中让我不得不重新温习下C语言,不得不去深入理解指针的含义。下面几点我列出了我在《Beginning C:From Novice to Professional》(Ivor Horton)书中学到的几点关于C指针的内容。内容很浅显,但过了4年,重新理解这些简单的知识点,有许多新的体会。所谓大道至简,指针的魅力也许就在这些简单的定义,微小的细节当中。

1-指针是存储地址的变量。
2-编译器必须知道指针所指的变量类型。没有这个信息,就不知道如何处理所指向的内存内容。
3-void*类型的指针可以包含任意类型的地址。
4-未初始化的指针是非常危险的,所以应该在声明指针的时候对他进行初始化。例如:

int *pointer = NULL;
表示不指向任何内存的位置。NULL在多个头文件中都包含。例如stdio.h string.h等。NULL也相当于数字0的指针。即
int *pointer = 0;
与上面的初始化等价。
int *pointer = &number;
pointer变量中存储的是number的地址。
*pointer则是存储在number中的值。
*又称取消引用运算符。

5-可以改变指针指向的地址,因此同一个指针也可以改变不同内存空间里的值。
6-指向常量的指针:

const int *pointer = &value;
不能通过指针改变所指向的值。但可以直接对value进行操作。也可以改变指针指向的地址。

7-常量指针:

int *const pointer = &value;
指针存储的地址不能改变。但可以改变指针指向的内容。

8-指向常量的常量指针:

const int *const pointer = &item;
不能改变存储在指针中的地址,不能改变指向的内容。

 


指针与数组

1-指针和数组似乎完全不同,但他们有非常紧密的关系,有时候还可以互换。
2-数组和指针重要的区别:

可以改变指针包含的地址;
不能改变数组名称引用的地址。
(使用数组名称而不带索引值,就等于引用数组的第一个元素的地址)


动态内存分配

1-int *pointer = (int*)malloc(5*sizeof(int));

malloc是一般函数,可为任意类型的数据分配内存。因此这个函数并不知道要分配的内存空间要做什么用,所以返回的是一个void类型指针。因此要将返回的地址做类型转换。(int*)

2-int *pointer = (int*)calloc(5,sizeof(int));

calloc()函数与malloc()函数相比有两个优点:
-它把内存分配为给定大小的数组;
-它初始化了所分配的内存,所有位都是0;

3-释放动态内存:

动态内存,应在不需要改内存时释放他们。堆上分配的内存会在程序结束时自动释放,但是为了避免出现内存泄漏,应在使用完后释放内存,或者退出程序时释放内存。
free(pointer);
同时应避免两次释放相同的内存区域,因为这种情况下,free操作是不确定的,因此结果也是无法预料的。