编程C本: 帖子 11 – 在C指针

1. 用C指针介绍

我们已经知道在过去使用的变量是确定的大小和数据类型变量. 他们称这种类型的变量是静态变量. 当你声明一个静态变量, 为可变数量的存储器单元将不使用其所有的存储单元或不的程序执行期间知道分配. 另一方面, 这种形式的静态变量将程序执行过程中存在的,尽管变化,该方案只使用 1 一次性.

一些限制可以使用静态变量时遇到:

  • 分配存储单元的平衡, 造成浪费的存储单元.
  • 缺少分配存储单元, 程序执行错误.

为了避免限制上, C语言为我们提供了具有以下特征的一个特殊的变量称为波动:

  • 程序执行过程中才会出现,而不是产生在启动程序.
  • 当运行程序, 变量的大小, 存储器和存储器地址被分配给该变量可以改变.
  • 在完成使用它可以解放节省内存空间. 然而,变化并不涉及某些我将不能够访问它们. 因此, C语言为我们提供了一种特殊类型的变量又克服这个, 指针变量是 (指针) 与特点:
  • 指针变量不包含包含该数据的地址数据或包含含有存储器的数据的地址.
  • 指针的大小不依赖于数据的类型.

2. 指针

每个变量声明为已分配给 1 某些存储区,其中 (地址) 不同. 指针 变量 用来存储变量的地址.

2.1 例

// e.g about pointer - code by nguyenvanquan7826
#include <stdio.h>

int main() 
{
    /* khai bao bien x va bien con tro px */
    int x, *px; 
    px = &x;
    /* &x : tra ve dia chi cua bien x
     * px = &x : gan dia chi cua bien x cho px hay px tro den x
     */

    x = 42;

    printf("Vi tri cua bien x la %p \n", &x);
    printf("Noi dung cua bien x la %d \n", x);
    printf("Vi tri cua bien x la %p \n", px);
    printf("Noi dung cua bien x la %d \n", *px);

    *px = 7826;
    printf("\n -------- \n\n");

    printf("Noi dung cua bien x la %d \n", x);
    printf("Noi dung cua bien x la %d \n", *px);

    return 0;
}

结果:

结果:
记录X LA 42
六三CUA以及X 0x7ffe064348fc
记录X LA 42

--------
记录X LA 7826
记录X LA 7826

通过这个开放的例子,我们可以得出以下几点:

该. 声明游标变量

对于每种类型的数据,我们分别具有该类型的指针变量.

类型 * 名称指针;

在上面的例子中,我们声明 1 int类型PX的指针变量.

B. 指针调节指向了

我们使用操作 & 对于地址 1 变量,然后分配一个地址指针.
名称指针= &变量;

Ç. 如何访问

用光标像素以上的有 2 虽然是许可:

  • PX : 获取地址,它保持 (点)
  • *PX : 得到它指向的内存的值.

在上面的例子中可以看出,在分配之后 PX = &x; 那么我们写的:

  • PX将相当于 &X
  • *像素等价于x. 并且可以在计算*像素被用于, 表达.

ð. 对指针的一些操作

// e.g about pointer - code by nguyenvanquan7826
#include <stdio.h>

int main() 
{
    /* khai bao bien x va 2 bien con tro px, qx */
    int x, *px, *qx; 
    px = &x;

    printf("Nhap gia tri cho vung nho px tro toi: ");
    scanf("%d", px); 
    /* px la con tro nen khong viet scanf("%d", &px);  */

    qx = px; /* gan gia tri cua px cho qx, qx cun tro toi x*/

    printf("Vi tri cua bien x la %p \n", &x);
    printf("Vi tri cua bien x la %p \n", px);
    printf("Vi tri cua bien x la %p \n", qx);
    printf("Noi dung cua bien x la %d \n", x);
    printf("Noi dung cua bien x la %d \n", *px);
    printf("Noi dung cua bien x la %d \n", *qx);

    // tang gia tri cua o nho len, <=> x = x + 7826
    *px += 7826; 
    printf("Noi dung cua bien x la %d \n", x);

    px++; 
    /* cong them mot don vi cho px
     *  => px tro toi vung nho tiep theo
     */

    printf("Vi tri px tro toi la %p \n", px);

    return 0;
}

结果:

输入海湾PX灰台岛值: 42
六三以及CUA X 0xbfba58a0
六三以及CUA X 0xbfba58a0
六三以及CUA X 0xbfba58a0
记录X LA 42
记录X LA 42
记录X LA 42
记录X LA 7868
六TRO排序PX你0xbfba58a4

对于例如,我们看到了一些操作后常见的指针: (除了许多其他操作).

  • 2 相同类型的指针变量可以分配给彼此或整数执行公共会计, 减 2 指针每. 在上面的例子中,我们执行计算:
  • 分配: Q X = PX; 当它接收到像素QX的值是变量x的地址, 即PX和QX并指着X. 此外,我们可以分配以下: Q X = PX + 2; 与QX, PX是一样的指针类型. 减法 2 相同类型的指针将返回 1 整数值 (INT). 这是距离 (一些元素) 之间 2 包括指针
  • 增加: 许可证,以增加或减少, 减法是在同一个指针运算的变量进行. 唯一的区别在于,它的上​​升和下降, 加或减根据单个字节,它有类型.
    首席执行官. 在上面的例子中,可以增加: PX ; 假定当该所指向的地址像素: 0xbfba58a0,然后使其增加其值是 (点的位置) 0xbfba58a4 (增加 4) 由于PX是int类型INT帐户的每个指针变量 4 在内存字节.
  • 此外,我们被允许通过* PX 数学改变变量x的值= 3; 在本质上,这操作是改变在存储器中的值 (地址) 该像素点, 这就导致了变量x的值根据改变.

你已经注意到了:

  • 根据不同的编译器或操作系统是不同类型的能力. (这是int类型占翻译 4 字节,但在其他服务占用 2 字节). 对于每种类型的存储您使用的sizeof() 但在所有 2 提到.
  • 另外,根据该操作系统的每个指针变量上, 不管是什么光标类型 (INT, 浮动, 双,...) 也占相同的字节数. 操作系统 32 位指针变量会计 4 字节, OS 64 位指针变量会计 8 字节.

3. 分配和恢复内存

该. 分配:

在此之前,一个小小的例子.

// e.g about pointer - code by nguyenvanquan7826
#include <stdio.h>

int main() 
{
    int *px;
    *px = 42;
    printf("Vi tri con tro px la %p \n", px);
    printf("Gia tri con tro px tro toi la %d \n", *px);
    return 0;
}

在编译时,它不会受益 (警告), 在运行时将无法运行该程序将退了出去.
其原因是,当游标变量声明像素新机只提供 2 字节来存储指针变量还没有为指针数据储存PX分配内存的地址. (类似的合作供应 2 大米为你做同样的,但不给你的土地你,镀金戒指公斤 ).

注意: 有一些编译器错误,但仍然无法正常运行,但最好的是,我们应该使用分配. 当您使用指针,我们将在后面讨论数组出现此错误最清楚.

好了,我们去的关键问题, 如何分配内存的指针.
为我们使用下面的函数库stdlib.h中指针分配内存.

  • 的malloc : 游标名= (指针类型 *) 的malloc (的sizeof(指针类型));
  • 释放calloc : 游标名= (指针类型 *) 的malloc (ñ, 的sizeof(指针类型));

在这种的sizeof(指针类型) 该类型的大小; n是的sizeof数(指针类型) 授.

// e.g about pointer - code by nguyenvanquan7826
#include <stdio.h>
#include <stdlib.h>

int main() 
{
    int *px, *qx;
    px = (int *) malloc(sizeof(int));
    qx = (int *) calloc(1, sizeof(int));

    printf("Vi tri con tro px la %p \n", px);
    printf("Gia tri con tro px tro toi la %d \n", *px);

    printf("Vi tri con tro qx la %p \n", qx);
    printf("Gia tri con tro qx tro toi la %d \n", *qx);
    return 0;
}

在这里,您注意: malloc和释放calloc,你只需明白什么时候使用malloc分配之间的唯一区别分配机PX 1 细胞的任何细胞,而不知道什么数据或者没有数据 (* PX如此宝贵如上) 释放calloc,太多,但也有其他 1 点分配后,机器会自动总是赋值 0 该指可变QX存储器单元, 新闻QX默认值是 0.
当分配指针 1 我们缺乏的,需要分配更多的工作的过程中,一定量的存储单元中,我们使用命令 realloc的:

游标名= (指针类型 *) realloc的 (游标名, 分配到的量 * 的sizeof(指针类型));

在这: =量分配到旧 + 新.
首席执行官: 起初,我们分配的指针像素 10 存储单元.
然后它要分配更多 5 更多的存储单元,所述量分配= 15.

B. 恢复和检查剩余内存

要恢复我们使用的内存分配函数 免费(游标名);

3. 光标的功能

正如在所有 用C置换函数 我们知道如何传递参数,b在HoanVi功能是按值传递,而不是传递按地址 (或参数) 所以尽管函数变量的值发生了变化,但功能完成后,该值尚未改变. 而且,我们将通过传递参数形成光标和指针b键的交换可以在存储单元的地址被交换修改该. 而当我们得到想要的结果.

// e.g about pointer - code by nguyenvanquan7826
#include <stdio.h>

void hoanVi(int *a, int *b) 
{
     int temp = *a;
     *a = *b;
     *b = temp;
}

int main() 
{
    int a = 42, b = 7826;
    printf("Truoc khi goi ham hoan vi: a = %d, b = %d \n", a, b);

    hoanVi(&a, &b);

    printf("Sau khi goi ham hoan vi: a = %d, b = %d \n", a, b);

    return 0;
}