提交 fdf3a1c3 编写于 作者: W wizardforcel

2019-08-22 21:12:22

上级 979f4b15
......@@ -2,15 +2,15 @@
> 原文: [https://beginnersbook.com/2014/01/c-pointers/](https://beginnersbook.com/2014/01/c-pointers/)
**指针**是存储另一个变量的地址的变量。与保存某种类型值的其他变量不同,指针保存变量的地址。例如,整数变量保(或者可以说是存储)整数值,但整数指针保存整数变量的地址。在本指南中,我们将在示例的帮助下讨论 [C 编程](https://beginnersbook.com/2014/01/c-tutorial-for-beginners-with-examples/)中的指针。
**指针**是存储另一个变量的地址的变量。与保存某种类型值的其他变量不同,指针保存变量的地址。例如,整数变量保(或者可以说是存储)整数值,但整数指针保存整数变量的地址。在本指南中,我们将在示例的帮助下讨论 [C 编程](https://beginnersbook.com/2014/01/c-tutorial-for-beginners-with-examples/)中的指针。
在我们讨论 C 中的**指针之前,让我们举一个简单的例子来理解变量地址的含义。**
#### 一个简单的例子,了解如何在没有指针的情况下访问变量的地址?
在这个程序中,我们有一个`int`类型的变量。`num`的值是 10,这个值必须存储在内存中的某个地方,对吧?为保存该变量值的每个变量分配一个内存空间,该内存空间有一个地址。例如,我们住在一所房子里,我们的房子有一个地址,帮助其他人找到我们的房子。同样,变量的值存储在内存地址中,这有助于 C 程序在需要时找到该值。
在这个程序中,我们有一个`int`类型的变量。`num`的值是 10,这个值必须存储在内存中的某个地方,对吧?为保存该变量值的变量分配一个内存空间,该内存空间有一个地址。例如,我们住在一所房子里,我们的房子有一个地址,帮助其他人找到我们的房子。同样,变量的值存储在内存地址中,这有助于 C 程序在需要时找到该值。
因此,假设分配给变量`num`的地址是`0x7fff5694dc58`,这意味着我们将分配给`num`的任何值都应该存储在以下位置:`0x7fff5694dc58`。见下图。
因此,假设分配给变量`num`的地址是`0x7fff5694dc58`,这意味着我们应该将赋给`num`的任何值存储在以下位置:`0x7fff5694dc58`。见下图。
```c
#include <stdio.h>
......@@ -72,14 +72,15 @@ Address of variable num is: 0x7fff5694dc58
### `&`地址运算符
我们在第一个例子中已经看到,我们可以使用`&`符号显示变量的地址。我用`&num`来访问变量`num`的地址。 **`&`运算符** 也称为**地址运算符**
我们在第一个例子中已经看到,我们可以使用`&`符号显示变量的地址。我用`&num`来访问变量`num`的地址。**`&`运算符**也称为**地址运算符**
```c
printf("Address of var is: %p", &num);
```
**注意事项:**`%p`是一种格式说明符,用于以十六进制格式显示地址。
既然您知道如何获取变量的地址,但**如何将该地址存储在其他变量中?** 这就是指针进入画面的地方。如本指南开头所述,C 编程中的指针用于保存另一个变量的地址。
既然您知道如何获取变量的地址,但**如何将该地址存储在其他变量中?** 这就是指针有用的地方。如本指南开头所述,C 编程中的指针用于保存另一个变量的地址。
**指针就像另一个变量,主要区别在于它存储另一个变量的地址而不是值。**
......@@ -99,6 +100,7 @@ float *p4 /*pointer to a float variable*/
以上是指针声明的几个例子。 **如果你需要一个指针来存储整数变量的地址,那么指针的数据类型应该是 `int`** 。同样的情况与其他数据类型有关。
通过使用`*`运算符,我们可以通过指针访问变量的值。
例如:
```c
......@@ -162,8 +164,7 @@ Address of pointer p is: 0x7fff5ed98c50
![pointer_memory_representation](img/aba872e79158955e21760c6182565d00.jpg)
让我们更多的例子来更好地理解它 -
让我们说我们有一个`char`变量`ch`和一个指向`ptr`的地址。
让我们举更多的例子来更好地理解它,让我们说我们有一个`char`变量`ch`和一个指向它的指针`ptr`
```c
char ch='a';
......@@ -231,6 +232,6 @@ Address of pointer p is: 0x7fff5d027c50
1) [**指向指针的指针**](https://beginnersbook.com/2014/01/c-pointer-to-pointer/) - 一个指针可以指向另一个指针(这意味着它可以存储另一个指针的地址),这样的指针称为双重指针或者指针的指针。
2) [**将指针传递给函数**](https://beginnersbook.com/2014/01/c-passing-pointers-to-functions/) - 指针也可以作为参数传递给函数,使用此功能可以通过引用调用函数,并且可以将数组传递给呼叫时的功能
2) [**将指针传递给函数**](https://beginnersbook.com/2014/01/c-passing-pointers-to-functions/) - 指针也可以作为参数传递给函数,使用此功能可以按引用调用函数,并且可以将数组传递给函数
3) [**函数指针**](https://beginnersbook.com/2014/01/c-function-pointers/) - 函数指针就像另一个指针,它用于存储函数的地址。函数指针也可用于调用 C 程序中的函数。
\ No newline at end of file
3) [**函数指针**](https://beginnersbook.com/2014/01/c-function-pointers/) - 函数指针就像另一个指针,它用于存储函数的地址。函数指针也可用于调用 C 程序中的函数。
......@@ -13,9 +13,10 @@ int **pr;
这里`pr`是一个双重指针。在双重指针的声明中必须有两个`*`
让我们借助图表来理解双重指针的概念:
![pointer-to-pointer or double pointer](img/6864d9fa06b928e688e39c78a000739e.jpg)
根据图表,`pr2`是一个普通指针,它保存整数变量`num`的地址。图中还有另一个指针`pr1`,它保存另一个指针 `pr2`的地址,这里的指针`pr1`是一个指向指针的指针(或双重指针)。
根据图表,`pr2`是一个普通指针,它保存整数变量`num`的地址。图中还有另一个指针`pr1`,它保存另一个指针`pr2`的地址,这里的指针`pr1`是一个指向指针的指针(或双重指针)。
**上图中的数值:**
......@@ -95,7 +96,7 @@ Value of Pointer pr1 is:  66X123X1
Address of Pointer pr1 is: XX661111
```
> 关于此程序的输出存在一些混淆,当您运行此程序时,您将看到类似于此的地址:`0x7fff54da7c58`。我以不同格式提供地址的原因是因为我希望您将此程序与上图相关联。我已经使用了上图中的确切地址值,因此您可以轻松地将此程序的输出与上图相关联。
> 关于此程序的输出存在一些混淆,当您运行此程序时,您将看到类似于此的地址:`0x7fff54da7c58`。我以不同格式提供地址的原因,是我希望您将此程序与上图相关联。我已经使用了上图中的确切地址值,因此您可以轻松地将此程序的输出与上图相关联。
您还可以使用以下简单公式了解程序逻辑:
......
......@@ -2,7 +2,7 @@
> 原文: [https://beginnersbook.com/2014/01/c-function-pointers/](https://beginnersbook.com/2014/01/c-function-pointers/)
[C 编程语言](https://beginnersbook.com/2014/01/c-tutorial-for-beginners-with-examples/)中,我们可以有一个指向 C 中称为**函数指针的函数的指针的概念。在本教程中,我们将学习如何声明函数指针以及如何使用此指针调用函数。要理解这个概念,你应该具备[函数](https://beginnersbook.com/2014/01/c-functions-examples/)和[指针在 C](https://beginnersbook.com/2014/01/c-pointers/) 中的基本知识。**
[C 编程语言](https://beginnersbook.com/2014/01/c-tutorial-for-beginners-with-examples/)中,我们可以有一个概念,称为**指向函数的指针**。在本教程中,我们将学习如何声明函数指针以及如何使用此指针调用函数。要理解这个概念,你应该具备[函数](https://beginnersbook.com/2014/01/c-functions-examples/)[指针](https://beginnersbook.com/2014/01/c-pointers/)的基本知识。**
## 如何声明函数指针?
......@@ -16,7 +16,7 @@ function_return_type(*Pointer_name)(function argument list)
double  (*p2f)(double, char)
```
这里 double 是函数的返回类型,`p2f`是函数指针的名称,`(double, char)`是这个函数的参数列表。这意味着此函数的第一个参数是`double`类型,第二个参数是`char`类型。
这里`double`是函数的返回类型,`p2f`是函数指针的名称,`(double, char)`是这个函数的参数列表。这意味着此函数的第一个参数是`double`类型,第二个参数是`char`类型。
让我们借助一个例子来理解这一点:这里我们有一个函数`sum`,它计算两个数字的总和并返回总和。我们创建了一个指向此函数的指针`f2p`,我们使用此函数指针`f2p`调用该函数。
......@@ -55,13 +55,14 @@ Output2: Call using function name: 23
```
**关于函数指针的一些要点:**
1.如注释中所述,您可以在单个语句中声明一个函数指针并为其分配函数,如下所示:
1\. 如注释中所述,您可以在单个语句中声明一个函数指针并为其赋值函数,如下所示:
```c
void (*fun_ptr)(int) = &fun;
```
2.您甚至可以从此语句中删除`&`符号,因为单独的函数名称表示函数地址。这意味着上面的语句也可以这样写:
2\. 您甚至可以从此语句中删除`&`符号,因为单独的函数名称表示函数地址。这意味着上面的语句也可以这样写:
```c
void (*fun_ptr)(int) = fun;
......
......@@ -2,15 +2,15 @@
> 原文: [https://beginnersbook.com/2014/01/c-passing-pointers-to-functions/](https://beginnersbook.com/2014/01/c-passing-pointers-to-functions/)
在本教程中,您将学习如何将指针作为参数传递给函数。要理解这个概念,你必须对 C 编程中的[指针](https://beginnersbook.com/2014/01/c-pointers/)[函数有基本的了解。](https://beginnersbook.com/2014/01/c-functions-examples/)
在本教程中,您将学习如何将指针作为参数传递给函数。要理解这个概念,你必须对 C 编程中的[指针](https://beginnersbook.com/2014/01/c-pointers/)[函数](https://beginnersbook.com/2014/01/c-functions-examples/)有基本的了解。
就像任何其他参数一样,指针也可以作为参数传递给函数。让我们举一个例子来了解这是如何完成的。
## 示例:将指针传递给 C 编程中的函数
## 示例:在 C 编程中将指针传递给函数
在这个例子中,我们传递一个指向函数的指针。当我们将指针作为参数而不是变量传递时,则传递变量的地址而不是值。因此,使用指针的函数所做的任何更改都是在传递的变量的地址处永久进行的。这种技术在 C 中称为引用调用。
在这个例子中,我们传递一个指向函数的指针。当我们将指针而不是变量作为参数传递时,则传递变量的地址而不是值。因此,使用指针的函数所做的任何更改,都是在传递的变量的地址处永久进行的。这种技术在 C 中称为按引用调用。
> 尝试没有指针的同一个程序,你会发现奖金金额不会反映在工资中,这是因为函数所做的更改将对函数的局部变量进行。当我们使用指针时,值会在变量的地址处更改
> 尝试没有指针的同一个程序,你会发现奖金金额不会反映在工资中,这是因为函数所做的更改将对函数的局部变量进行。当我们使用指针时,值会在变量的地址处更改
```c
#include <stdio.h>
......@@ -42,7 +42,7 @@ Final salary: 12000
## 示例 2:使用指针交换两个数字
这是最流行的示例之一,显示如何使用引用调用交换数字。
这是最流行的示例之一,显示如何使用引用调用交换数字。
> 尝试没有指针的程序,你会看到数字没有交换。原因与我们在第一个例子中看到的相同。
......
......@@ -4,15 +4,6 @@
在本指南中,我们将学习如何使用 [C 编程](https://beginnersbook.com/2014/01/c-tutorial-for-beginners-with-examples/)语言对文件执行输入/输出(I/O)操作。
## C 文件 I/O - 目录
1\. [打开文件](#1)
2\. [读取文件](#2)
3\. [写入文件](#3)
4\. [关闭文件](#4)
5\. [读取和写入文件](#5)
6\. [在 C](#6) 中读写二进制文件
在我们详细讨论每个操作之前,让我们来看一个简单的 C 程序:
### 一个简单的 C 程序,用于打开,读取和关闭文件
......@@ -45,9 +36,10 @@ int main()
在上面的程序中,我们在`r`模式下打开文件`newfile.txt`,读取文件内容并在控制台上显示。让我们详细了解每个操作:
## 1.打开文件
## 1\. 打开文件
`fopen()`函数用于打开文件。
**语法:**
```c
......@@ -55,9 +47,11 @@ FILE pointer_name = fopen ("file_name", "Mode");
```
`pointer_name`可以是您选择的任何东西。
`file_name`是您要打开的文件的名称。在此处指定完整路径,如`C:\\myfiles\\newfile.txt`
打开文件时,需要指定模式。我们用来读取文件的模式是`r`,它是“只读模式”。
**例如:**
```c
......@@ -68,7 +62,9 @@ fp = fopen("C:\\myfiles\\newfile.txt", "r");
第一个字符的地址存储在`pointer fp`中。
**如何检查文件是否已成功打开?**
如果文件未成功打开,则指针将被赋予`NULL`值,因此您可以编写如下逻辑:
此代码将检查文件是否已成功打开。如果文件未打开,则会向用户显示错误消息。
```c
......@@ -85,24 +81,24 @@ if (fpr == NULL)
### 各种文件打开模式:
使用`fopen()`函数打开文件,打开时可以根据需要使用以下任何一种模式。
**模式`r`:**这是一种只读模式,这意味着如果文件在`r`模式下打开,它将不允许您编写和修改它的内容。当`fopen()`成功打开文件时,它返回文件第一个字符的地址,否则返回`NULL`
**模式`w`:**这是一种只写模式。 `fopen()`函数在指定文件不存在时创建新文件,如果无法打开文件,则返回`NULL`
**模式`r`**:这是一种只读模式,这意味着如果文件在`r`模式下打开,它将不允许您编写和修改它的内容。当`fopen()`成功打开文件时,它返回文件第一个字符的地址,否则返回`NULL`
**模式`w`**:这是一种只写模式。`fopen()`函数在指定文件不存在时创建新文件,如果无法打开文件,则返回`NULL`
**模式`a`:**使用此模式内容可以附加在现有文件的末尾。与模式`w`类似,如果文件不存在,`fopen()`会创建一个新文件。在不成功的打开时,它返回`NULL`
文件指针指向:文件的最后一个字符。
**模式`a`**:使用此模式,内容可以附加在现有文件的末尾。与模式`w`类似,如果文件不存在,`fopen()`会创建一个新文件。在打开不成功时,它返回`NULL`。文件指针指向:文件的最后一个字符。
**模式`r+`:**此模式与模式`r`相同;但是,您可以对在此模式下打开的文件执行各种操作。您可以读取,写入和修改以`r+`模式打开的文件内容。
文件指针指向:文件的第一个字符。
**模式`r+`**:此模式与模式`r`相同;但是,您可以对在此模式下打开的文件执行各种操作。您可以读取,写入和修改以`r+`模式打开的文件内容。文件指针指向:文件的第一个字符。
**模式`w+`:**与可以执行的操作相同的模式`w`相同;可以在此模式下读取,写入和修改文件。
**模式`a+`:**与模式`a`相同;您可以在文件中读取和附加数据,但在此模式下不允许进行内容修改。
**模式`w+`**:与可以执行的操作相同的模式`w`相同;可以在此模式下读取,写入和修改文件。
## 2.读取文件
**模式`a+`**:与模式`a`相同;您可以在文件中读取和附加数据,但在此模式下不允许进行内容修改。
## 2\. 读取文件
要读取文件,我们必须首先使用任何模式打开它,例如,如果您只想读取文件,然后以`r`模式打开它。根据文件打开期间选择的模式,我们可以对文件执行某些操作。
### C 程序读取文件
### C 程序读取文件
**`fgetc()`:**该函数从当前指针的位置读取字符,成功读取后,将指针移动到文件中的下一个字符。一旦指针到达文件的末尾,该函数返回 **EOF(文件结束)**。我们在程序中使用了 **EOF** 来确定文件的结尾。
......@@ -134,7 +130,7 @@ int main()
## 3.写入文件
编写文件,我们必须以支持写入的模式打开文件。例如,如果以`r`模式打开文件,则无法写入文件,因为`r`是只允许读取的只读模式。
写入文件,我们必须以支持写入的模式打开文件。例如,如果以`r`模式打开文件,则无法写入文件,因为`r`是只允许读取的只读模式。
## 示例:C 程序写入文件
......@@ -165,7 +161,7 @@ int main()
}
```
## 4.关闭文件
## 4\. 关闭文件
```c
fclose(fp);
......@@ -221,15 +217,18 @@ int main()
## 如何在文件中读/写(I/O)字符串 - `fgets`和`fputs`
在这里,我们将讨论如何将字符串读写到文件中。
在这里,我们将讨论如何读字符串和将其写到文件中。
```c
char *fgets(char *s, int rec_len, FILE *fpr)
```
**`s`** :存储字符串的字符数组。
**`rec_len`** :输入记录的长度。
**`fpr`** :指向输入文件的指针。
让我们举一个例子:
### 在 C 编程中从文件中读取字符串的示例
......@@ -270,11 +269,10 @@ int main()
fgets(str, 10, fpr)
```
这里 **`str`** 表示从文件中读取字符串后存储字符串的字符串(`char`数组)。
**`10`** 是每次需要读取的字符串的长度。
**`fpr`** 是指向文件的指针,将被读取。
这里 **`str`**表示从文件中读取字符串后,存储字符串的缓冲区(`char`数组)。**`10`** 是每次需要读取的字符串的长度。**`fpr`** 是指向文件的指针,将被读取。
**为什么我用`if(fgets(str, 10, fpr) ==NULL)`作为判断文件结尾的逻辑?**
在上面的例子中,我们用`ch == EOF`来知道文件的结尾。这里我们使用了这个逻辑,因为当没有更多的记录可供读取时,`fgets`返回`NULL`
### C 程序 - 将字符串写入文件
......@@ -283,8 +281,9 @@ fgets(str, 10, fpr)
int fputs ( const char * s, FILE * fpw );
```
`char *s` - char 数组。
`FILE *fpw` - 指向文件的指针(FILE 类型),将被写入。
`char *s` - `char`数组。
`FILE *fpw` - 指向文件的指针(`FILE`类型),将被写入。
```c
#include <stdio.h>
......@@ -320,16 +319,18 @@ int main()
}
```
**`fputs`有两个参数 -**
**`fputs`有两个参数**
```c
fputs(str, fpw)
```
**`str`** - `str`表示存储字符串的数组。
**`fpw`** - 指向输出文件的`FILE`指针,需要在其中写入记录。
**关于`fputs`的注意事项:默认情况下**
`fputs`在写入每条记录后不会添加新行,为了手动执行此操作 - 每次写入文件后都可以使用以下语句。
```c
......@@ -338,7 +339,7 @@ fputs("\n", fpw);
## C 文件 I/O:二进制文件
到目前为止,我们已经学习了文本文件的文件操作,如果文件是二进制文件(例如`.exe`文件)。上述程序不适用于二进制文件,但处理二进制文件时有一些细微的变化。主要区别在于**文件名&amp;模式。** 让我们在一个例子的帮助下理解这一点。可以说我有两个二进制文件`bin1.exe & bin2.exe`- 我想将 `bin1.exe`的内容复制到`bin2.exe`
到目前为止,我们已经学习了文本文件的文件操作,如果文件是二进制文件(例如`.exe`文件)。上述程序不适用于二进制文件,但处理二进制文件时有一些细微的变化。主要区别在于**文件名和模式。** 让我们在一个例子的帮助下理解这一点。可以说我有两个二进制文件`bin1.exe``bin2.exe`- 我想将`bin1.exe`的内容复制到`bin2.exe`
### 示例:在 C 中读取和写入二进制文件
......@@ -387,4 +388,4 @@ int main()
}
```
**注意:文件打开模式为`rb`和`wb`而不是`r`&amp; `w`**
\ No newline at end of file
**注意:文件打开模式为`rb`和`wb`而不是`r`和`w`**
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册