C中的指针:C编程中的指针是什么?类型

C 语言中的指针是什么?

C 语言中的指针是一个存储另一个变量地址的变量。指针还可以用于引用另一个指针函数。指针可以递增/递减,即指向下一个/上一个内存位置。指针的目的是节省内存空间并实现更快的执行时间。

如何在 C 语言中使用指针

如果我们声明一个 int 类型的变量 v,v 将实际存储一个值。

How to Use Pointers in C

v 现在等于零。

然而,每个变量除了值之外,还有它的地址(或者简单地说,它在内存中的位置)。可以通过在变量名前面加上一个“&”来检索地址。

How to Use Pointers in C

如果在屏幕上打印变量的地址,它看起来会像一个完全随机的数字(而且,它可能每次运行都不同)。

让我们在 C 指针示例中实际尝试一下

How to Use Pointers in C

此程序的输出是 -480613588。

那么,什么是指针?指针不存储值,而是存储变量的地址。


指针变量

Int *y = &v;

变量 指针
存储在命名存储/内存地址中的 一个变量,它指向另一个变量的存储/内存地址

声明指针

与变量一样,C 语言中的指针在程序中使用之前必须声明。指针可以命名为任何您想要的名称,只要它们符合 C 的命名规则。指针声明具有以下形式。

data_type * pointer_variable_name;

此处,

  • 数据类型 是指针的基类型,属于 C 的变量类型,并指示指针指向的变量的类型。
  • 星号(*:与乘法使用的星号相同),即间接运算符,用于声明指针。

在此 C 指针教程中,让我们看一些有效的指针声明

int    *ptr_thing;            /* pointer to an integer */ 
int *ptr1,thing;/* ptr1 is a pointer to type integer and thing is an integer variable */
double    *ptr2;    /* pointer to a double */
float    *ptr3;      /* pointer to a float */
char    *ch1 ;       /* pointer to a character */
float  *ptr, variable;/*ptr is a pointer to type float and variable is an ordinary float variable */

初始化指针

声明指针后,我们像标准变量一样用变量地址对其进行初始化。如果在程序中使用未初始化的 C 语言指针,结果可能是不可预测的,甚至可能导致灾难性的后果。

为了获取变量的地址,我们使用“&”运算符,将其放在需要地址的变量名之前。指针初始化使用以下语法完成。

指针语法

 pointer = &variable;

下面给出了一个简单的指针说明程序

#include <stdio.h>
int main()
{
   int a=10;    //variable declaration
   int *p;      //pointer variable declaration
   p=&a;        //store address of variable a in pointer p
   printf("Address stored in a variable p is:%x\n",p);  //accessing the address
   printf("Value stored in a variable p is:%d\n",*p);   //accessing the value
   return 0;
}

输出

Address stored in a variable p is:60ff08
Value stored in a variable p is:10
运算符 含义
* 服务 2 个目的

  1. 指针声明
  2. 返回所引用变量的值
& 只服务 1 个目的

  • 返回变量的地址

C 语言中的指针类型

以下是 C 语言中不同类型的指针

空指针

我们可以在声明指针时通过赋值 null 值来创建一个空指针。当指针没有任何地址分配时,此方法很有用。空指针始终包含值 0。

以下程序说明了空指针的使用

#include <stdio.h>
int main()
{
	int *p = NULL; 	//null pointer
	printf(“The value inside variable p is:\n%x”,p);
	return 0;
}

输出

The value inside variable p is:
0

void 指针

在 C 编程中,void 指针也称为通用指针。它没有任何标准数据类型。void 指针是通过使用关键字 void 创建的。它可以用于存储任何变量的地址。

以下程序说明了 void 指针的使用

#include <stdio.h>
int main()
{
void *p = NULL; 	//void pointer
printf("The size of pointer is:%d\n",sizeof(p));
return 0;
}

输出

The size of pointer is:4

野指针

如果指针未初始化为任何值,则该指针称为野指针。这些类型的 C 指针效率不高,因为它们可能指向未知的内存位置,这可能导致程序出现问题,甚至导致程序崩溃。在处理野指针时应始终小心。

以下程序说明了野指针的使用

#include <stdio.h>
int main()
{
int *p; 	//wild pointer
printf("\n%d",*p);
return 0;
}

输出

timeout: the monitored command dumped core
sh: line 1: 95298 Segmentation fault      timeout 10s main

C 语言中的其他指针类型如下

  • 悬空指针
  • 复杂指针
  • 近指针
  • 远指针
  • 大指针

直接和间接访问指针

在 C 语言中,有两种等效的方法可以访问和操作变量内容

  • 直接访问:我们直接使用变量名
  • 间接访问:我们使用指向该变量的指针

让我们通过下面的程序来理解这一点

#include <stdio.h>
/* Declare and initialize an int variable */
int var = 1;
/* Declare a pointer to int */
int *ptr;
int main( void )
{
/* Initialize ptr to point to var */
ptr = &var;
/* Access var directly and indirectly */
printf("\nDirect access, var = %d", var);
printf("\nIndirect access, var = %d", *ptr);
/* Display the address of var two ways */
printf("\n\nThe address of var = %d", &var);
printf("\nThe address of var = %d\n", ptr);
/*change the content of var through the pointer*/
*ptr=48;
printf("\nIndirect access, var = %d", *ptr);
return 0;}

在编译程序没有任何错误之后,结果是

Direct access, var = 1
Indirect access, var = 1

The address of var = 4202496
The address of var = 4202496

Indirect access, var = 48

C 语言中的指针算术

指针操作在下图总结

Pointer Arithmetic in C
指针操作

优先级操作(优先权)

在使用 C 指针时,我们必须遵守以下优先级规则

  • 运算符 * 和 & 的优先级与一元运算符(否定!、增量++、减量–)相同。
  • 在同一个表达式中,一元运算符 *、&、!、++、– 从右到左求值。

如果 P 指针指向 X 变量,那么 * P 可以在任何可以写 X 的地方使用。

以下表达式是等效的

int X =10
int *P = &Y;
For the above code, below expressions are true
表达式 等效表达式
Y=*P+1

*P=*P+10

*P+=2

++*P

(*P)++

Y=X+1

X=X+10

X+=2

++X

X++

在后一种情况下,需要括号:由于一元运算符 * 和 ++ 是从右到左求值的,如果没有括号,指针 P 将被递增,而不是 P 所指向的对象。

下表显示了处理 C 指针时可以使用的算术和基本操作

操作 解释
赋值 int *P1,*P2
P1=P2;
P1 和 P2 指向同一个整数变量
递增和递减 Int *P1;
P1++;P1– ;
添加偏移量(常量) 这允许指针在表中移动 N 个元素。
指针将按变量类型的字节数乘以 N 来增加或减少。
P1+5;

C 指针与数组(附带示例)

传统上,我们使用数组索引来访问数组元素,但通过使用指针可以消除这种方法。指针可以轻松访问每个数组元素。

#include <stdio.h>
int main()
{
    int a[5]={1,2,3,4,5};   //array initialization
    int *p;     //pointer declaration
               /*the ptr points to the first element of the array*/

    p=a; /*We can also type simply ptr==&a[0] */
    
    printf("Printing the array elements using pointer\n");
    for(int i=0;i<5;i++)    //loop for traversing array elements
    {
        	printf("\n%x",*p);  //printing array elements
        	p++;    //incrementing to the next element, you can also write p=p+1
    }
    return 0;
}

输出

1
2
3
4
5

将一个特定的数字加到一个指针上会将指针位置移动到加法运算得到的值。假设 p 是一个当前指向内存位置 0 的指针,如果我们执行以下加法运算,p+1,那么它将按此方式执行

C Pointers & Arrays

指针加法/增量

由于 p 当前指向位置 0,将 1 相加后,值将变为 1,因此指针将指向内存位置 1。

C 指针与字符串(附带示例)

字符串是由 char 对象组成的数组,以 null 字符 '\0' 结尾。我们可以使用指针来操作字符串。此 C 指针示例解释了本节内容

#include <stdio.h>
#include <string.h>
int main()
{
char str[]="Hello Guru99!";
char *p;
p=str;
printf("First character is:%c\n",*p);
p =p+1;
printf("Next character is:%c\n",*p);
printf("Printing all the characters in a string\n");
p=str;  //reset the pointer
for(int i=0;i<strlen(str);i++)
{
printf("%c\n",*p);
p++;
}
return 0;
}

输出

First character is:H
Next character is:e
Printing all the characters in a string
H
e
l
l
o

G
u
r
u
9
9
!

处理字符串的另一种方法是使用指针数组,如下一个程序所示

#include <stdio.h>
int main(){
char *materials[ ] = {  "iron",  "copper",  "gold"};
printf("Please remember these materials :\n");
int i ;
for (i = 0; i < 3; i++) {
  printf("%s\n", materials[ i ]);}
  return 0;}

输出

Please remember these materials:
iron
copper
gold

C 语言中指针的优点

  • 指针对于访问内存位置很有用。
  • 指针为访问数组结构元素提供了有效的方法。
  • 指针也用于动态内存分配和释放。
  • 指针用于形成复杂的数据结构,如链表、图、树等。

C 语言中指针的缺点

  • 指针有点难理解。
  • 指针可能导致各种错误,例如段错误,或者访问根本不需要的内存位置。
  • 如果为指针提供了不正确的值,它可能会导致内存损坏。
  • 指针也负责内存泄漏。
  • 与变量相比,指针相对较慢。
  • 程序员发现指针非常难以处理;因此,程序员有责任仔细操作指针。

摘要

  • 指针只不过是一个存储数据的内存位置。
  • 指针用于访问内存位置。
  • 有各种类型的指针,例如空指针、野指针、void 指针和其他类型的指针。
  • 指针可与数组和字符串一起使用,以更有效地访问元素。
  • 我们可以创建函数指针来动态调用函数。
  • 可以对指针进行算术运算,称为指针算术。
  • 指针也可以指向函数,这使得在定义指针数组时很容易调用不同的函数。
  • 当您想处理不同的变量数据类型时,可以使用类型转换 void 指针。