C 中的指针:C 编程中的指针是什么?类型
C 语言中的指针是什么?
- 指针 在 C 语言中,指针是存储另一个变量地址的变量。指针也可用于引用另一个指针函数。指针可以递增/递减,即指向下一个/上一个内存位置。指针的目的是节省内存空间并实现更快的执行时间。
如何在 C 中使用指针
如果我们声明一个 int 类型的变量 v,v 实际上会存储一个值。
v 现在等于零。
但是,每个变量除了值之外,还有它的地址(或者简单地说,它在内存中的位置)。通过在变量名前添加一个与号 (&) 可以检索地址。
如果在屏幕上打印变量的地址,它将看起来就像一个完全随机的数字(而且,每次运行它可能都会有所不同)。
让我们用 C 示例中的指针来实践一下
该程序的输出是-480613588。
那么,什么是指针呢?指针不存储值,而是存储变量的地址。
指针变量
int *y = &v;
变量 | 指针 |
---|---|
A 折扣值 存储在一个 命名 存储/内存地址 | A 变量 这 点 存储/内存地址 另一个 变量 |
声明指针
和变量一样,指针 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
Opera器 | 意 |
---|---|
* | 一举两得
|
& | 仅用于一个目的
|
C 语言中的指针类型
以下是不同的 C 语言中的指针类型:
空指针
我们可以在指针声明期间分配空值来创建空指针。当您没有为指针分配任何地址时,此方法很有用。空指针始终包含值 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
空指针
In C程序设计,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 中的指针算术
指针操作总结如下图所示
优先操作(优先顺序)
使用 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++ |
在后一种情况下,需要使用括号:因为一元运算符 * 和 ++ 是从右到左进行求值的,如果没有括号,指针 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,则它将按以下方式执行:
由于p当前指向的位置是0,加1之后值会变成1,因此指针会指向内存位置1。
C 指针和字符串示例
字符串是 char 对象的数组,以空字符 '\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 语言中指针的缺点
- 指针理解起来有点复杂。
- 指针可能导致各种错误,例如分段错误,或者访问根本不需要的内存位置。
- 如果给指针提供了不正确的值,则可能会导致内存损坏。
- 指针也是造成内存泄漏的原因。
- 指针比变量相对慢。
- 程序员发现使用指针非常困难;因此小心操作指针是程序员的责任。
总结
- 指针不过是存储数据的内存位置而已。
- 指针用于访问内存位置。
- 指针有多种类型,例如空指针,野指针,空指针和其他类型的指针。
- 指针可与数组和字符串一起使用,以更有效地访问元素。
- 我们可以创建函数指针来动态调用函数。
- 可以对指针进行算术运算,这称为指针算术。
- 指针还可以指向函数,这使得在定义指针数组的情况下可以轻松调用不同的函数。
- 当您想要处理不同的变量数据类型时,您可以使用类型转换空指针。