C 指针基础知识用例子解释——第一部分
任何在 Linux 环境下工作的人(不仅仅是开发人员),都应该了解 C 编程语言的基础知识并编写一些基本的 C 程序。
这篇文章是我们正在进行的关于 C 编程语言的系列文章的一部分。
指针的概念是 C/C++ 语言最强大的基础之一。
通过指针,开发人员可以直接从他/她的代码中访问内存,这使得与内存相关的操作非常快。但是,一如既往,强大的力量伴随着巨大的责任。
开发人员必须非常小心地使用指针,以避免一些可能成为调试噩梦的问题。
在本文中,我们将通过 C 语言中的示例来研究指针的基本概念。
什么是指针?
与其他可以存储值的普通变量不同,指针是可以保存变量地址的特殊变量。由于它们存储变量的内存地址,因此指针通常被称为“指向变量”。让我们试着理解这个概念。
如上图所示:
- 普通变量“var”的内存地址为 1001,值为 50。
- 指针变量有自己的地址2047,但存储为1001,即变量“var”的地址
如何声明一个指针?
一个指针声明为:
<pointer type> *<pointer-name>
在上面的声明中:
- pointer-type :它指定指针的类型。它可以是int、char、float等。这个类型指定了这个指针可以存储其地址的变量的类型。
- 指针名称:它可以是用户指定的任何名称。从专业上讲,每个代码都遵循一些编码风格。指针名称通常以“p”开头或以“ptr”结尾
指针声明的一个例子可以是:
char *chptr;
在上面的声明中,'char' 表示指针类型,chptr 是指针的名称,而星号 '*' 表示 'chptr' 是一个指针变量。
如何初始化指针?
指针的初始化方式如下:
<pointer declaration(except semicolon)> = <address of a variable>
OR
<pointer declaration>
<name-of-pointer> = <address of a variable>
请注意,上面的变量类型应该与指针类型相同。(虽然这不是一个严格的规则,但对于初学者来说应该记住这一点)。
例如 :
char ch = 'c';
char *chptr = &ch; //initialize
OR
char ch = 'c';
char *chptr;
chptr = &ch //initialize
在上面的代码中,我们声明了一个字符变量 ch 来存储值 'c'。现在,我们声明了一个字符指针 'chptr' 并用变量 'ch' 的地址初始化它。
请注意,'&' 运算符用于访问任何类型变量的地址。
如何使用指针?
指针可以在两种情况下使用。
上下文1:用于访问指针存储的内存地址的变量的地址。
再次考虑以下代码:
char ch = 'c';
char *chptr = &ch;
现在,每当我们在上面两行之后的代码中引用名称“chptr”时,编译器都会尝试获取该指针变量包含的值,即指针指向的变量(ch)的地址。即'chptr' 给出的值将等于'&ch'。
例如 :
char *ptr = chptr;
'chptr' 持有的值(在这种情况下是变量 'ch' 的地址)被分配给新的指针 'ptr'。
上下文 2:用于访问指针存储其内存地址的变量的值。
继续上面使用的一段代码:
char ch = 'c';
char t;
char *chptr = &ch;
t = *chptr;
我们看到在上面的最后一行中,我们在指针名称之前使用了“*”。这个星号运算符有什么作用?
好吧,当应用于指针变量名称时(如上面的最后一行),此运算符会产生此指针指向的变量的值。这意味着,在这种情况下,'*chptr' 将产生 chptr 持有的地址中保存的值。由于 'chptr' 保存变量 'ch' 的地址并且 'ch' 的值为 'c',所以 '*chptr' 产生 'c'。
与指针一起使用时,星号“*”运算符也称为“值”运算符。
C 指针的一个例子
考虑以下代码:
代码 :
#include <stdio.h>
int main(void)
{
char ch = 'c';
char *chptr = &ch;
int i = 20;
int *intptr = &i;
float f = 1.20000;
float *fptr = &f;
char *ptr = "I am a string";
printf("\n [%c], [%d], [%f], [%c], [%s]\n", *chptr, *intptr, *fptr, *ptr, ptr);
return 0;
}
输出 :
$ ./pointers
[c], [20], [1.200000], [I], [I am a string]
要调试 C 程序,请使用gdb。上面的代码涵盖了所有常见的指针。他们中的前三个现在很容易理解,所以让我们专注于第四个。在第四个例子中,一个字符指针指向一个字符串。
在 C 中,字符串只不过是一个字符数组。所以我们在 C 中没有凝视指针。它也是用于字符串的字符指针。
现在,谈到字符串,当我们将指针指向字符串时,默认情况下它保存字符串第一个字符的地址。让我们试着更好地理解它。
内存中的字符串 'I am String' 被放置为:
1001 1002 1003 1004 1005 1006 1007 1008 1009 1010
I a m S t r i n g \0
由于每个字符占用一个字节,因此它们在内存中的放置方式如上。注意最后一个字符,它是一个空字符,在 C 中默认放置在每个字符串的末尾。这个空字符表示字符串的结尾。
现在回到重点,任何指向字符串的字符指针都存储字符串的第一个字符的地址。在上面的代码中,'ptr' 保存了字符 'I' 的地址,即 1001。现在,当我们将 'value of' 运算符 '*' 应用于 'ptr' 时,我们打算获取地址 1001 处的值,即'I' 因此当我们打印 '*ptr' 时,我们得到 'I' 作为输出。
此外,如果我们将格式说明符指定为 '%s' 并使用 'ptr'(包含字符串的起始地址),则使用 printf 打印完整的字符串。这个概念是 %s 说明符需要字符串的起始字节的地址来显示完整的字符串,我们使用 'ptr' 提供它(我们知道它保存字符串的起始字节地址)。我们可以将其视为上面输出中的最后一个打印。
指针作为结构对象
考虑以下代码:
代码:
#include<stdio.h>
struct st{
int a;
char ch;
};
int main(void)
{
struct st obj;
struct st *stobj = &obj;
stobj->a = 5;
stobj->ch = 'a';
printf("\n [%d] [%c]\n", stobj->a, stobj->ch);
return 0;
}
输出:
$ ./pointers
[5] [a]
在上面的代码中,我们声明了一个“struct st”类型的指针 stobj。现在由于指针类型是一个结构,所以它指向的地址必须是一个“struct st”类型变量(在这种情况下是“obj”)。另一个有趣的部分是如何使用指针变量 'stobj' 访问结构元素。是的,在处理指针对象时,使用箭头运算符 -> 而不是 '.' 是一种标准。运算符(如果我们使用 'obj' 来访问结构元素,它会被使用)。
总而言之,在本文中,我们从头开始研究 C 中指针的概念,然后在我们对更复杂的主题(例如将指针用作结构对象)的理解的基础上慢慢建立。这是一个基础教程,我们将在本文的第二部分介绍更复杂的指针概念。
- 点赞
- 收藏
- 关注作者
评论(0)