Cprogramming 简明教程

Pointers in C

What is a Pointer in C?

C 指针是派生数据类型,用于存储其他变量的地址,还可以用来访问和操控在该位置存储的变量数据。指针被视为派生数据类型。

C pointer is the derived data type that is used to store the address of another variable and can also be used to access and manipulate the variable’s data stored at that location. The pointers are considered as derived data types.

使用指针,您可以访问和修改存储在内存中的数据,在函数之间有效传递数据,以及创建链表、树和图等动态数据结构。

With pointers, you can access and modify the data located in the memory, pass the data efficiently between the functions, and create dynamic data structures like linked lists, trees, and graphs.

Pointer Declaration

若要声明一个指针,请使用 dereferencing operator ( )*后跟数据类型。

To declare a pointer, use the dereferencing operator ()* followed by the data type.

Syntax

指针变量声明的一般形式为 −

The general form of a pointer variable declaration is −

type *var-name;

在此处, type 是指示器的基本类型;它必须是一个有效的 C data type ,而 var-name 是指示器变量的名称。用于声明指向器的星号 * 与用于乘法的星号相同。然而,在此声明中,星号用于将变量指定为一个指向器。

Here, type is the pointer’s base type; it must be a valid C data type and var-name is the name of the pointer variable. The asterisk * used to declare a pointer is the same asterisk used for multiplication. However, in this statement the asterisk is being used to designate a variable as a pointer.

Example of Valid Pointer Variable Declarations

请查看一些有效的指针声明 −

Take a look at some of the valid pointer declarations −

int    *ip;    /* pointer to an integer */
double *dp;    /* pointer to a double */
float  *fp;    /* pointer to a float */
char   *ch     /* pointer to a character */

所有指向器(无论是整数、浮点数、字符还是其他)的值的实际数据类型都是相同的,是一个表示内存地址的长十六进制数字。不同数据类型的指向器之间的唯一区别是由指向器指向的 variableconstant 的数据类型。

The actual data type of the value of all pointers, whether integer, float, character, or otherwise, is the same, a long hexadecimal number that represents a memory address. The only difference between pointers of different data types is the data type of the variable or constant that the pointer points to.

Pointer Initialization

声明一个指针变量后,您需要使用 address of (&) operator 将其初始化为另一个变量的地址。此过程称为 referencing a pointer

After declaring a pointer variable, you need to initialize it with the address of another variable using the address of (&) operator. This process is known as referencing a pointer.

Syntax

以下是要初始化指针变量的语法 −

The following is the syntax to initialize a pointer variable –

pointer_variable = &variable;

Example

以下是一个指针初始化的示例 −

Here is an example of pointer initialization –

int x = 10;
int *ptr = &x;

此处,x 是一个整数变量,ptr 是一个整数指针。指针 ptr 正在用 x 初始化。

Here, x is an integer variable, ptr is an integer pointer. The pointer ptr is being initialized with x.

Referencing and Dereferencing Pointers

指针引用内存中的位置。从该存储位置获取存储值的过程称为 dereferencing the pointer

A pointer references a location in memory. Obtaining the value stored at that location is known as dereferencing the pointer.

在 C 中,了解以下两个运算符在指针机制中的目的是很重要的 −

In C, it is important to understand the purpose of the following two operators in the context of pointer mechanism −

  1. The & Operator − It is also known as the "Address-of operator". It is used for Referencing which means taking the address of an existing variable (using &) to set a pointer variable.

  2. The * Operator − It is also known as the "dereference operator". Dereferencing a pointer is carried out using the * operator to get the value from the memory address that is pointed by the pointer.

指针用于按引用传递参数。如果程序员希望某个函数对参数的修改对函数的调用者可见,则该函数非常有用。此功能还可以从函数返回多个值。

Pointers are used to pass parameters by reference. This is useful if a programmer wants a function’s modifications to a parameter to be visible to the function’s caller. This is also useful for returning multiple values from a function.

Access and Manipulate Values using Pointer

可以访问和操作由指针指向的变量的值,方法是使用指针变量。您需要在指针变量中使用星号 (*) 符号来访问和操作变量的值。

The value of the variable which is pointed by a pointer can be accessed and manipulated by using the pointer variable. You need to use the asterisk (*) sign with the pointer variable to access and manipulate the variable’s value.

Example

在下面的示例中,我们取值为初始值的一个整数变量,并将其更改为新值。

In the below example, we are taking an integer variable with its initial value and changing it with the new value.

#include <stdio.h>

int main() {
  int x = 10;

  // Pointer declaration and initialization
  int * ptr = & x;

  // Printing the current value
  printf("Value of x = %d\n", * ptr);

  // Changing the value
  * ptr = 20;

  // Printing the updated value
  printf("Value of x = %d\n", * ptr);

  return 0;
}
Value of x = 10
Value of x = 20

How to Use Pointers?

要使用 C 语言中的指针,您需要声明一个指针变量,然后使用另一个变量的地址对其进行初始化,然后可以通过解除引用来使用它,以获取和更改指针指向的变量的值。

To use the pointers in C language, you need to declare a pointer variable, then initialize it with the address of another variable, and then you can use it by dereferencing to get and change the value of the variables pointed by the pointer.

您可以将指向器用于任何类型的变量,例如整数、浮点数、字符串等。您还可以将指向器用于导出数据类型,例如 arraystructureunion 等。

You can use pointers with any type of variable such as integer, float, string, etc. You can also use pointers with derived data types such as array, structure, union, etc.

Example

在下方的示例中,我们使用指针来获取不同类型变量的值。

In the below example, we are using pointers for getting values of different types of variables.

#include <stdio.h>

int main() {
  int x = 10;
  float y = 1.3f;
  char z = 'p';

  // Pointer declaration and initialization
  int * ptr_x = & x;
  float * ptr_y = & y;
  char * ptr_z = & z;

  // Printing the values
  printf("Value of x = %d\n", * ptr_x);
  printf("Value of y = %f\n", * ptr_y);
  printf("Value of z = %c\n", * ptr_z);

  return 0;
}
Value of x = 10
Value of y = 1.300000
Value of z = p

Size of a Pointer Variable

指针变量所占据的内存(或大小)并不取决于其所指向变量的类型。指针的大小取决于系统架构。

The memory (or, size) occupied by a pointer variable does not depend on the type of the variable it is pointing to. The size of a pointer depends on the system architecture.

Example

在下方的示例中,我们打印不同类型指针的大小:

In the below example, we are printing the size of different types of pointers:

#include <stdio.h>

int main() {
  int x = 10;
  float y = 1.3f;
  char z = 'p';

  // Pointer declaration and initialization
  int * ptr_x = & x;
  float * ptr_y = & y;
  char * ptr_z = & z;

  // Printing the size of pointer variables
  printf("Size of integer pointer : %lu\n", sizeof(ptr_x));
  printf("Size of float pointer : %lu\n", sizeof(ptr_y));
  printf("Size of char pointer : %lu\n", sizeof(ptr_z));

  return 0;
}
Size of integer pointer : 8
Size of float pointer : 8
Size of char pointer : 8

Examples of C Pointers

练习以下示例以了解指针的概念 -

Practice the following examples to learn the concept of pointers –

Example 1: Using Pointers in C

以下示例演示如何在 C 中使用 &* 操作符执行与指针相关的操作 −

The following example shows how you can use the & and * operators to carry out pointer-related opeartions in C −

#include <stdio.h>

int main(){

   int  var = 20;   /* actual variable declaration */
   int  *ip;        /* pointer variable declaration */

   ip = &var;   /* store address of var in pointer variable*/

   printf("Address of var variable: %p\n", &var);

   /* address stored in pointer variable */
   printf("Address stored in ip variable: %p\n", ip);

   /* access the value using the pointer */
   printf("Value of *ip variable: %d\n", *ip );

   return 0;
}

执行代码并检查其输出 −

Execute the code and check its output −

Address of var variable: 0x7ffea76fc63c
Address stored in ip variable: 0x7ffea76fc63c
Value of *ip variable: 20

Example: Print Value and Address of an Integer

我们声明一个 int 变量并显示其值和地址 −

We will declare an int variable and display its value and address −

#include <stdio.h>

int main(){

   int var = 100;

   printf("Variable: %d \t Address: %p", var, &var);

   return 0;
}

运行代码并检查其输出:

Run the code and check its output −

Variable: 100   Address: 0x7ffc62a7b844

Example: Integer Pointer

在此示例中, var 的地址存储在 intptr 变量中,使用 & 操作符

In this example, the address of var is stored in the intptr variable with & operator

#include <stdio.h>

int main(){

   int var = 100;
   int *intptr = &var;

   printf("Variable: %d \nAddress of Variable: %p \n\n", var, &var);
   printf("intptr: %p \nAddress of intptr: %p \n\n", intptr, &intptr);

   return 0;
}

运行代码并检查其输出:

Run the code and check its output −

Variable: 100
Address of Variable: 0x7ffdcc25860c

intptr: 0x7ffdcc25860c
Address of intptr: 0x7ffdcc258610

Example 5

现在让我们举一个 float 变量的示例并查找其地址 −

Now let’s take an example of a float variable and find its address −

#include <stdio.h>

int main(){

   float var1 = 10.55;

   printf("var1: %f \n", var1);
   printf("Address of var1: %d", &var1);
}

运行代码并检查其输出:

Run the code and check its output −

var1: 10.550000
Address of var1: 1512452612

我们可以看到该变量的地址(就该问题而言,任何类型的变量)都是一个整数。因此,如果我们尝试将其存储在 "float" 类型的指针变量中,看看会发生什么 −

We can see that the address of this variable (any type of variable for that matter) is an integer. So, if we try to store it in a pointer variable of "float" type, see what happens −

float var1 = 10.55;
int *intptr = &var1;

编译器不接受它,并报告以下 error

The compiler doesn’t accept this, and reports the following error

initialization of 'int *' from incompatible pointer type
'float *' [-Wincompatible-pointer-types]

Note: 变量的类型及其指针的类型必须相同。

Note: The type of a variable and the type of its pointer must be same.

在 C 中,变量具有定义其大小和存储值方式的特定数据类型。使用匹配类型(例如 float *)声明指针会在指针和它所指向的数据之间强加 “类型兼容性”。

In C, variables have specific data types that define their size and how they store values. Declaring a pointer with a matching type (e.g., float *) enforces "type compatibility" between the pointer and the data it points to.

在 C 中,不同的数据类型占据不同的内存空间。例如,“int” 通常占用 4 个字节,而 “float” 可能占用 4 或 8 个字节,具体取决于系统。对指针进行整数加法或减法会将它们基于它们所指向数据的尺寸在内存中移动。

Different data types occupy different amounts of memory space in C. For example, an "int" typically takes 4 bytes, while a "float" might take 4 or 8 bytes depending on the system. Adding or subtracting integers from pointers moves them in memory based on the size of the data they point to.

Example: Float Pointer

在此示例中,我们声明了一个 “float *” 类型的变量 “floatptr”。

In this example, we declare a variable "floatptr" of "float *" type.

#include <stdio.h>

int main(){

   float var1 = 10.55;
   float *floatptr = &var1;

   printf("var1: %f \nAddress of var1: %p \n\n",var1, &var1);
   printf("floatptr: %p \nAddress of floatptr: %p \n\n", floatptr, &floatptr);
   printf("var1: %f \nValue at floatptr: %f", var1, *floatptr);

   return 0;
}
var1: 10.550000
Address of var1: 0x7ffc6daeb46c

floatptr: 0x7ffc6daeb46c
Address of floatptr: 0x7ffc6daeb470

Pointer to Pointer

我们可能有一个指针变量,它存储另一个指针本身的地址。

We may have a pointer variable that stores the address of another pointer itself.

pointer variable

在上图中,“a” 是一个普通 “int” 变量,其指针是 “x”。反过来,变量存储 “x” 的地址。

In the above figure, "a" is a normal "int" variable, whose pointer is "x". In turn, the variable stores the address of "x".

请注意,将 “y” 声明为 “int **” 以表明它是指向另一个指针变量的指针。显然,“y” 将返回 “x” 的地址,而 “*y” 是 “x” 中的值(这是 “a” 的地址)。

Note that "y" is declared as "int **" to indicate that it is a pointer to another pointer variable. Obviously, "y" will return the address of "x" and "*y" is the value in "x" (which is the address of "a").

要从 “y” 获得 “a” 的值,我们需要使用表达式 “ *y". Usually, "y" will be called as the *pointer to a pointer ”。

To obtain the value of "a" from "y", we need to use the expression "*y". Usually, "y" will be called as the *pointer to a pointer.

Example

请看以下示例:

Take a look at the following example −

#include <stdio.h>

int main(){

   int var = 10;
   int *intptr = &var;
   int **ptrptr = &intptr;

   printf("var: %d \nAddress of var: %d \n\n",var, &var);
   printf("inttptr: %d \nAddress of inttptr: %d \n\n", intptr, &intptr);
   printf("var: %d \nValue at intptr: %d \n\n", var, *intptr);
   printf("ptrptr: %d \nAddress of ptrtptr: %d \n\n", ptrptr, &ptrptr);
   printf("intptr: %d \nValue at ptrptr: %d \n\n", intptr, *ptrptr);
   printf("var: %d \n*intptr: %d \n**ptrptr: %d", var, *intptr, **ptrptr);

   return 0;
}

运行代码并检查其输出:

Run the code and check its output −

var: 10
Address of var: 951734452

inttptr: 951734452
Address of inttptr: 951734456

var: 10
Value at intptr: 10

ptrptr: 951734456
Address of ptrtptr: 951734464
intptr: 951734452
Value at ptrptr: 951734452

var: 10
*intptr: 10
**ptrptr: 10

您既可以拥有 pointer to an array ,也可以拥有使用 struct 定义的派生类型。指针具有重要的应用。它们在通过传递引用调用函数时使用。指针还有助于克服函数仅返回单个值的局限性。使用指针,您还可以获得返回多个值或数组的效果。

You can have a pointer to an array as well as a derived type defined with struct. Pointers have important applications. They are used while calling a function by passing the reference. Pointers also help in overcoming the limitation of a function’s ability to return only a single value. With pointers, you can get the effect of returning multiple values or arrays.

NULL Pointers

如果您没有确切的地址要分配,那么将 NULL 值分配给指针变量始终是一种好习惯。这在变量声明时完成。分配了 NULL 的指针称为 null 指针。

It is always a good practice to assign a NULL value to a pointer variable in case you do not have an exact address to be assigned. This is done at the time of variable declaration. A pointer that is assigned NULL is called a null pointer.

NULL 指针是一个常量,在多个标准库中定义的值为“0”。

The NULL pointer is a constant with a value of "0" defined in several standard libraries.

Example

请考虑以下程序 −

Consider the following program −

#include <stdio.h>

int main(){

   int *ptr = NULL;

   printf("The value of ptr is : %x\n", ptr);

   return 0;
}

编译并执行上述代码后,将产生以下结果 −

When the above code is compiled and executed, it produces the following result −

The value of ptr is 0

在大多数操作系统中,程序不允许访问地址“0”处的内存,因为该内存已被操作系统保留。

In most operating systems, programs are not permitted to access memory at address "0" because that memory is reserved by the operating system.

内存地址“0”具有特殊意义;它表示指针不打算指向可访问的内存位置。但按照惯例,如果指针包含空(零)值,则假定它指向无处。

The memory address "0" has a special significance; it signals that the pointer is not intended to point to an accessible memory location. But by convention, if a pointer contains the null (zero) value, it is assumed to point to nothing.

要检查空指针,您可以使用以下 if 语句:

To check for a null pointer, you can use an if statement as follows −

if(ptr)     /* succeeds if p is not null */
if(!ptr)    /* succeeds if p is null */

Address of the Variables

如您所知,每个变量都是一个内存位置,每个内存位置都有其定义的地址,可以使用和号(&)运算符访问该地址,该运算符表示内存中的一个地址。

As you know, every variable is a memory location and every memory location has its address defined which can be accessed using the ampersand (&) operator, which denotes an address in memory.

Example

考虑以下示例,它将打印所定义变量的地址:

Consider the following example, which prints the address of the variables defined −

#include <stdio.h>

int main(){

   int  var1;
   char var2[10];

   printf("Address of var1 variable: %x\n", &var1);
   printf("Address of var2 variable: %x\n", &var2);

   return 0;
}

Output

当以上代码经过编译和执行时,它将打印变量的地址:

When the above code is compiled and executed, it will print the address of the variables −

Address of var1 variable: 61e11508
Address of var2 variable: 61e1150e

Pointers in Detail

指针有很多简单的概念,它们对 C 编程非常重要。任何 C 程序员都应清楚以下重要的指针概念:

Pointers have many but easy concepts and they are very important to C programming. The following important pointer concepts should be clear to any C programmer −

Sr.No

Concept & Description

1

Pointer arithmeticThere are four arithmetic operators that can be used in pointers: ++, --, +, -

2

Array of pointersYou can define arrays to hold a number of pointers.

3

Pointer to pointerC allows you to have pointer on a pointer and so on.

4

Passing pointers to functions in CPassing an argument by reference or by address enable the passed argument to be changed in the calling function by the called function.

5

Return pointer from functions in CC allows a function to return a pointer to the local variable, static variable, and dynamically allocated memory as well.