数组和指针
约 6346 字大约 21 分钟
2023-04-02
数组
C 语言支持数组数据结构,它可以存储一个固定大小的相同类型元素的顺序集合。数组是用来存储一系列数据,但它往往被认为是一系列相同类型的变量。
数组的声明并不是声明一个个单独的变量,比如 number0、number1、...、number99,而是声明一个数组变量,比如 numbers,然后使用 numbers[0]、numbers[1]、...、numbers[99] 来代表一个个单独的变量。数组中的特定元素可以通过索引访问。
所有的数组都是由连续的内存位置组成。最低的地址对应第一个元素,最高的地址对应最后一个元素。
数组中的特定元素可以通过索引访问,第一个索引值为0。
声明数组
在 C 中要声明一个数组,需要指定元素的类型和元素的数量,如下所示:
type arrayName[arraySize];
这叫做一维数组。arraySize 必须是一个大于零的整数常量,type 可以是任意有效的 C 数据类型。例如,要声明一个类型为 int 的包含 10 个元素的数组 balance,声明语句如下:
int balance[10];
现在 balance 是一个可用的数组,可以容纳 10 个类型为 double 的数字。
初始化数组
在 C 中,可以逐个初始化数组,也可以使用一个初始化语句,如下所示:
int balance[5] = {1000, 2, 3, 7, 50};
大括号 { } 之间的值的数目不能大于在数组声明时在方括号 [ ] 中指定的元素数目。
如果省略掉了数组的大小,数组的大小则为初始化时元素的个数。因此,如果:
int balance[] = {1000, 2, 3, 7, 50};
将创建一个数组,它与前一个实例中所创建的数组是完全相同的。下面是一个为数组中某个元素赋值的实例:
balance[4] = 50;
上述的语句把数组中第五个元素的值赋为 50。所有的数组都是以 0 作为它们第一个元素的索引,也被称为基索引,数组的最后一个索引是数组的总大小减去 1。
访问数组元素
数组元素可以通过数组名称加索引进行访问。元素的索引是放在方括号内,跟在数组名称的后边。例如:
int salary = balance[9];
上面的语句将把数组中第 10 个元素的值赋给 salary 变量。下面的实例使用了上述的三个概念,即,声明数组、数组赋值、访问数组:
#include <stdio.h>
int main()
{
int n[10]; /* n 是一个包含 10 个整数的数组 */
int i = 0;
int j = 0;
/* 初始化数组元素 */
for (i = 0; i < 10; i++)
{
n[i] = i + 100; /* 设置元素 i 为 i + 100 */
}
/* 输出数组中每个元素的值 */
for (j = 0; j < 10; j++)
{
printf("Element[%d] = %d\n", j, n[j]);
}
return 0;
}
当上面的代码被编译和执行时,会产生下列结果:
Element[0] = 100
Element[1] = 101
Element[2] = 102
Element[3] = 103
Element[4] = 104
Element[5] = 105
Element[6] = 106
Element[7] = 107
Element[8] = 108
Element[9] = 109
多维数组
C 语言支持多维数组。多维数组声明的一般形式如下:
type name[size1][size2]...[sizeN];
例如,下面的声明创建了一个三维 5 . 10 . 4 整型数组:
int threedim[5][10][4];
二维数组
多维数组最简单的形式是二维数组。一个二维数组,在本质上,是一个一维数组的列表。声明一个 x 行 y 列的二维整型数组,形式如下:
type arrayName[x][y];
其中,type 可以是任意有效的 C 数据类型,arrayName 是一个有效的 C 标识符。一个二维数组可以被认为是一个带有 x 行和 y 列的表格。
数组中的每个元素是使用形式为 a[i] [j] 的元素名称来标识的,其中 a 是数组名称,i 和 j 是唯一标识 a 中每个元素的下标。
初始化二维数组
多维数组可以通过在括号内为每行指定值来进行初始化。下面是一个带有 3 行 4 列的数组。
int a[3][4] =
{
{ 0, 1, 2, 3 }, /* 初始化索引号为 0 的行 */
{ 4, 5, 6, 7 }, /* 初始化索引号为 1 的行 */
{ 8, 9, 10, 11 } /* 初始化索引号为 2 的行 */
};
内部嵌套的括号是可选的,下面的初始化与上面是等同的:
int a[3][4] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
访问二维数组元素
二维数组中的元素是通过使用下标(即数组的行索引和列索引)来访问的。例如:
int val = a[2][3];
上面的语句将获取数组中第 3 行第 4 个元素。下面的程序,将使用嵌套循环来处理二维数组:
#include <stdio.h>
int main()
{
/* 一个带有 5 行 2 列的数组 */
int a[5][2] = { { 0, 0 }, { 1, 2 }, { 2, 4 }, { 3, 6 }, { 4, 8 } };
int i = 0;
int j = 0;
/* 输出数组中每个元素的值 */
for (i = 0; i < 5; i++)
{
for (j = 0; j < 2; j++)
{
printf("a[%d][%d] = %d\n", i, j, a[i][j]);
}
}
return 0;
}
当上面的代码被编译和执行时,会产生下列结果:
a[0][0]: 0
a[0][1]: 0
a[1][0]: 1
a[1][1]: 2
a[2][0]: 2
a[2][1]: 4
a[3][0]: 3
a[3][1]: 6
a[4][0]: 4
a[4][1]: 8
如上所述,可以创建任意维度的数组,但是一般情况下,创建的数组是一维数组和二维数组。
传递数组给函数
如果想要在函数中传递一个一维数组作为参数,必须以下面三种方式来声明函数形式参数,这三种声明方式的结果是一样的,因为每种方式都会告诉编译器将要接收一个整型指针。同样地,也可以传递一个多维数组作为形式参数。
方式 1
形式参数是一个指针(在下一节中介绍到有关指针的知识):
void myFunction(int *param)
{
...
}
方式 2
形式参数是一个已定义大小的数组:
void myFunction(int param[10])
{
...
}
方式 3
形式参数是一个未定义大小的数组:
void myFunction(int param[])
{
...
}
实例
下面这个函数,它把数组作为参数,同时还传递了另一个参数,根据所传的参数,会返回数组中各元素的平均值:
double getAverage(int arr[], int size)
{
int i;
double avg;
double sum;
for (i = 0; i < size; ++i) {
sum += arr[i];
}
avg = sum / size;
return avg;
}
现在调用上面的函数,如下所示:
#include <stdio.h>
/* 函数声明 */
double getAverage(int arr[], int size);
int main()
{
/* 带有 5 个元素的整型数组 */
int balance[5] = { 1000, 2, 3, 17, 50 };
double avg;
/* 传递一个指向数组的指针作为参数 */
avg = getAverage(balance, 5);
/* 输出返回值 */
printf("平均值是: %f ", avg);
return 0;
}
当上面的代码被编译和执行时,会产生下列结果:
平均值是: 214.400000
可以看到,就函数而言,数组的长度是无关紧要的,因为 C 不会对形式参数执行边界检查。
从函数返回数组
C 语言不允许返回一个完整的数组作为函数的参数。但是,可以通过指定不带索引的数组名来返回一个指向数组的指针。
如果想要从函数返回一个一维数组,必须声明一个返回指针的函数,如下:
int * myFunction()
{
...
}
另外,C 不支持在函数外返回局部变量的地址,除非定义局部变量为 static 变量。
下面的函数,它会生成 10 个随机数,并使用数组来返回它们,具体如下:
#include <stdio.h>
/* 要生成和返回随机数的函数 */
int* getRandom()
{
static int r[10];
int i;
/* 设置种子 */
srand((unsigned)time(NULL));
for (i = 0; i < 10; ++i)
{
r[i] = rand();
printf("r[%d] = %d\n", i, r[i]);
}
return r;
}
/* 要调用上面定义函数的主函数 */
int main()
{
/* 一个指向整数的指针 */
int* p = NULL;
int i;
p = getRandom();
for (i = 0; i < 10; i++)
{
printf("*(p + %d) : %d\n", i, *(p + i));
}
return 0;
}
当上面的代码被编译和执行时,会产生下列结果:
r[0] = 313959809
r[1] = 1759055877
r[2] = 1113101911
r[3] = 2133832223
r[4] = 2073354073
r[5] = 167288147
r[6] = 1827471542
r[7] = 834791014
r[8] = 1901409888
r[9] = 1990469526
*(p + 0) : 313959809
*(p + 1) : 1759055877
*(p + 2) : 1113101911
*(p + 3) : 2133832223
*(p + 4) : 2073354073
*(p + 5) : 167288147
*(p + 6) : 1827471542
*(p + 7) : 834791014
*(p + 8) : 1901409888
*(p + 9) : 1990469526
指向数组的指针
数组名是一个指向数组中第一个元素的常量指针。因此,在下面的声明中:
double balance[50];
balance 是一个指向 &balance[0] 的指针,即数组 balance 的第一个元素的地址。因此,下面的程序片段把 p 赋值为 balance 的第一个元素的地址:
double *p;
double balance[10];
p = balance;
使用数组名作为常量指针是合法的,反之亦然。因此,*(balance + 4) 是一种访问 balance[4] 数据的合法方式。
一旦把第一个元素的地址存储在 p 中,就可以使用 p、(p+1)、*(p+2) 等来访问数组元素。下面的实例演示了上面讨论到的这些概念:
#include <stdio.h>
int main()
{
/* 带有 5 个元素的整型数组 */
double balance[5] = { 1000.0, 2.0, 3.4, 17.0, 50.0 };
double* p;
int i;
p = balance;
/* 输出数组中每个元素的值 */
printf("使用指针的数组值\n");
for (i = 0; i < 5; i++) {
printf("*(p + %d) : %f\n", i, *(p + i));
}
printf("使用 balance 作为地址的数组值\n");
for (i = 0; i < 5; i++) {
printf("*(balance + %d) : %f\n", i, *(balance + i));
}
return 0;
}
当上面的代码被编译和执行时,会产生下列结果:
使用指针的数组值
*(p + 0) : 1000.000000
*(p + 1) : 2.000000
*(p + 2) : 3.400000
*(p + 3) : 17.000000
*(p + 4) : 50.000000
使用 balance 作为地址的数组值
*(balance + 0) : 1000.000000
*(balance + 1) : 2.000000
*(balance + 2) : 3.400000
*(balance + 3) : 17.000000
*(balance + 4) : 50.000000
在上面的实例中,p 是一个指向 double 型的指针,这意味着它可以存储一个 double 类型的变量。一旦有了 p 中的地址,**p 将给出存储在 p 中相应地址的值,正如上面实例中所演示的。
指针
每一个变量都有一个内存位置,每一个内存位置都定义了可使用连字号(&)运算符访问的地址,它表示了在内存中的一个地址。下面的实例将输出定义的变量地址:
#include <stdio.h>
int main()
{
int var1;
char var2[10];
printf("var1 变量的地址: %x\n", &var1);
printf("var2 变量的地址: %x\n", &var2);
return 0;
}
当上面的代码被编译和执行时,它会产生类似下列结果:
var1 变量的地址: bff5a400
var2 变量的地址: bff5a3f6
通过上面的实例,了解了什么是内存地址以及如何访问它。接下来让看看什么是指针。
什么是指针?
指针是一个变量,其值为另一个变量的地址,即,内存位置的直接地址。就像其他变量或常量一样,必须在使用指针存储其他变量地址之前,对其进行声明。指针变量声明的一般形式为:
type *var-name;
在这里,type 是指针的基类型,它必须是一个有效的 C 数据类型,var-name 是指针变量的名称。用来声明指针的星号 * 与乘法中使用的星号是相同的。但是,在这个语句中,星号是用来指定一个变量是指针。以下是有效的指针声明:
int *ip; /* 一个整型的指针 */
char *ch /* 一个字符型的指针 */
所有指针的值的实际数据类型,不管是整型、浮点型、字符型,还是其他的数据类型,都是一样的,都是一个代表内存地址的长的十六进制数。不同数据类型的指针之间唯一的不同是,指针所指向的变量或常量的数据类型不同。
如何使用指针?
使用指针时会频繁进行以下几个操作:定义一个指针变量、把变量地址赋值给指针、访问指针变量中可用地址的值。这些是通过使用一元运算符 * 来返回位于操作数所指定地址的变量的值。下面的实例涉及到了这些操作:
#include <stdio.h>
int main()
{
int var = 20; /* 实际变量的声明 */
int* ip = NULL; /* 指针变量的声明 */
ip = &var; /* 在指针变量中存储 var 的地址 */
printf("Address of var variable: %x\n", &var);
/* 在指针变量中存储的地址 */
printf("Address stored in ip variable: %x\n", ip);
/* 使用指针访问值 */
printf("Value of *ip variable: %d\n", *ip);
return 0;
}
当上面的代码被编译和执行时,会产生下列结果:
Address of var variable: bffd8b3c
Address stored in ip variable: bffd8b3c
Value of *ip variable: 20
NULL 指针
在变量声明的时候,如果没有确切的地址可以赋值,为指针变量赋一个 NULL 值是一个良好的编程习惯。赋为 NULL 值的指针被称为空指针。
NULL 指针是一个定义在标准库中的值为零的常量。
#include <stdio.h>
int main ()
{
int *ptr = NULL;
printf("ptr 的值是 %x\n", ptr );
return 0;
}
当上面的代码被编译和执行时,会产生下列结果:
ptr 的值是 0
在大多数的操作系统上,程序不允许访问地址为 0 的内存,因为该内存是操作系统保留的。然而,内存地址 0 有特别重要的意义,它表明该指针不指向一个可访问的内存位置。但按照惯例,如果指针包含空值(零值),则假定它不指向任何东西。
如需检查一个空指针,可以使用 if 语句,如下所示:
if (ptr) /* 如果 p 非空,则完成 */
if (!ptr) /* 如果 p 为空,则完成 */
指针的算术运算
C 指针是一个用数值表示的地址。因此,可以对指针执行算术运算。可以对指针进行四种算术运算:++、--、+、-。
假设 ptr 是一个指向地址 1000 的整型指针,是一个 32 位的整数,让对该指针执行下列的算术运算:
ptr++
在执行完上述的运算之后,ptr 将指向位置 1004,因为 ptr 每增加一次,它都将指向下一个整数位置,即当前位置往后移 4 个字节。这个运算会在不影响内存位置中实际值的情况下,移动指针到下一个内存位置。如果 ptr 指向一个地址为 1000 的字符,上面的运算会导致指针指向位置 1001,因为下一个字符位置是在 1001。
递增一个指针
喜欢在程序中使用指针代替数组,因为变量指针可以递增,而数组不能递增,数组可以看成一个指针常量。下面的程序递增变量指针,以便顺序访问数组中的每一个元素:
#include <stdio.h>
const int MAX = 3;
int main()
{
int var[] = {10, 100, 200};
int i;
int *ptr = NULL;
/* 指针中的数组地址 */
ptr = var;
for (i = 0; i < MAX; i++)
{
printf("Address of var[%d] = %x\n", i, ptr);
printf("Value of var[%d] = %d\n", i, *ptr);
/* 移动到下一个位置 */
ptr++;
}
return 0;
}
当上面的代码被编译和执行时,会产生下列结果:
Address of var[0] = bf882b30
Value of var[0] = 10
Address of var[1] = bf882b34
Value of var[1] = 100
Address of var[2] = bf882b38
Value of var[2] = 200
递减一个指针
同样地,对指针进行递减运算,即把值减去其数据类型的字节数,如下所示:
#include <stdio.h>
const int MAX = 3;
int main()
{
int var[] = {10, 100, 200};
int i, *ptr;
/* 指针中最后一个元素的地址 */
ptr = &var[MAX - 1];
for (i = MAX; i > 0; i--) {
printf("Address of var[%d] = %x\n", i, ptr);
printf("Value of var[%d] = %d\n", i, *ptr);
/* 移动到下一个位置 */
ptr--;
}
return 0;
}
当上面的代码被编译和执行时,会产生下列结果:
Address of var[3] = bfedbcd8
Value of var[3] = 200
Address of var[2] = bfedbcd4
Value of var[2] = 100
Address of var[1] = bfedbcd0
Value of var[1] = 10
指针的比较
指针可以用关系运算符进行比较,如 ==、< 和 >。如果 p1 和 p2 指向两个相关的变量,比如同一个数组中的不同元素,则可对 p1 和 p2 进行大小比较。
下面的程序修改了上面的实例,只要变量指针所指向的地址小于或等于数组的最后一个元素的地址 &var[MAX - 1],则把变量指针进行递增:
#include <stdio.h>
const int MAX = 3;
int main()
{
int var[] = {10, 100, 200};
int i;
int *ptr = NULL;
/* 指针中第一个元素的地址 */
ptr = var;
i = 0;
while (ptr <= &var[MAX - 1])
{
printf("Address of var[%d] = %x\n", i, ptr);
printf("Value of var[%d] = %d\n", i, *ptr);
/* 指向上一个位置 */
ptr++;
i++;
}
return 0;
}
当上面的代码被编译和执行时,会产生下列结果:
Address of var[0] = bfdbcb20
Value of var[0] = 10
Address of var[1] = bfdbcb24
Value of var[1] = 100
Address of var[2] = bfdbcb28
Value of var[2] = 200
指针数组
在讲解指针数组的概念之前,先让来看一个实例,它用到了一个由 3 个整数组成的数组:
#include <stdio.h>
const int MAX = 3;
int main()
{
int var[] = {10, 100, 200};
int i;
for (i = 0; i < MAX; i++)
{
printf("Value of var[%d] = %d\n", i, var[i]);
}
return 0;
}
当上面的代码被编译和执行时,会产生下列结果:
Value of var[0] = 10
Value of var[1] = 100
Value of var[2] = 200
可能有一种情况,想要让数组存储指向 int 或 char 或其他数据类型的指针。下面是一个指向整数的指针数组的声明:
int *ptr[MAX];
在这里,把 ptr 声明为一个数组,由 MAX 个整数指针组成。因此,ptr 中的每个元素,都是一个指向 int 值的指针。下面的实例用到了三个整数,它们将存储在一个指针数组中,如下所示:
#include <stdio.h>
const int MAX = 3;
int main()
{
int var[] = {10, 100, 200};
int i = 0;
int *ptr[MAX] = {NULL};
for (i = 0; i < MAX; i++)
{
ptr[i] = &var[i]; /* 赋值为整数的地址 */
}
for (i = 0; i < MAX; i++)
{
printf("Value of var[%d] = %d\n", i, *ptr[i]);
}
return 0;
}
当上面的代码被编译和执行时,会产生下列结果:
Value of var[0] = 10
Value of var[1] = 100
Value of var[2] = 200
也可以用一个指向字符的指针数组来存储一个字符串列表,如下:
#include <stdio.h>
const int MAX = 4;
int main()
{
char* names[] =
{
"Zara Ali",
"Hina Ali",
"Nuha Ali",
"Sara Ali",
};
int i = 0;
for (i = 0; i < MAX; i++)
{
printf("Value of names[%d] = %s\n", i, names[i]);
}
return 0;
}
当上面的代码被编译和执行时,会产生下列结果:
Value of names[0] = Zara Ali
Value of names[1] = Hina Ali
Value of names[2] = Nuha Ali
Value of names[3] = Sara Ali
指向指针的指针
指向指针的指针是一种多级间接寻址的形式,或者说是一个指针链。通常,一个指针包含一个变量的地址。当定义一个指向指针的指针时,第一个指针包含了第二个指针的地址,第二个指针指向包含实际值的位置。
一个指向指针的指针变量必须如下声明,即在变量名前放置两个星号。例如,下面声明了一个指向 int 类型指针的指针:
int **var;
当一个目标值被一个指针间接指向到另一个指针时,访问这个值需要使用两个星号运算符,如下面实例所示:
#include <stdio.h>
int main()
{
int var;
int* ptr = NULL;
int** pptr = NULL;
var = 3000;
/* 获取 var 的地址 */
ptr = &var;
/* 使用运算符 & 获取 ptr 的地址 */
pptr = &ptr;
/* 使用 pptr 获取值 */
printf("Value of var = %d\n", var);
printf("Value available at *ptr = %d\n", *ptr);
printf("Value available at **pptr = %d\n", **pptr);
return 0;
}
当上面的代码被编译和执行时,会产生下列结果:
Value of var = 3000
Value available at *ptr = 3000
Value available at **pptr = 3000
传递指针给函数
C 语言允许传递指针给函数,只需要简单地声明函数参数为指针类型即可。
下面的实例中,传递一个无符号的 long 型指针给函数,并在函数内改变这个值:
#include <stdio.h>
#include <time.h>
void getSeconds(unsigned long* par);
int main()
{
unsigned long sec;
getSeconds(&sec);
/* 输出实际值 */
printf("Number of seconds: %ld\n", sec);
return 0;
}
void getSeconds(unsigned long* par)
{
/* 获取当前的秒数 */
*par = time(NULL);
return;
}
当上面的代码被编译和执行时,会产生下列结果:
Number of seconds :1294450468
能接受指针作为参数的函数,也能接受数组作为参数,如下所示:
#include <stdio.h>
/* 函数声明 */
double getAverage(int* arr, int size);
int main()
{
/* 带有 5 个元素的整型数组 */
int balance[5] = { 1000, 2, 3, 17, 50 };
double avg;
/* 传递一个指向数组的指针作为参数 */
avg = getAverage(balance, 5);
/* 输出返回值 */
printf("Average value is: %f\n", avg);
return 0;
}
double getAverage(int* arr, int size)
{
int i = 0;
int sum = 0;
double avg;
for (i = 0; i < size; ++i)
{
sum += arr[i];
}
avg = (double)sum / size;
return avg;
}
当上面的代码被编译和执行时,会产生下列结果:
Average value is: 214.40000
从函数返回指针
在上一章中,已经了解了 C 语言中如何从函数返回数组,类似地,C 允许从函数返回指针。为了做到这点,必须声明一个返回指针的函数,如下所示:
int* myFunction()
{
...
}
另外,C 不支持在函数外返回局部变量的地址,除非定义局部变量为 static 变量。
现在,让来看下面的函数,它会生成 10 个随机数,并使用表示指针的数组名(即第一个数组元素的地址)来返回它们,具体如下:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
/* 要生成和返回随机数的函数 */
int* getRandom()
{
static int r[10];
int i;
/* 设置种子 */
srand((unsigned)time(NULL));
for (i = 0; i < 10; ++i)
{
r[i] = rand();
printf("%d\n", r[i]);
}
return r;
}
/* 要调用上面定义函数的主函数 */
int main()
{
/* 一个指向整数的指针 */
int* p;
int i;
p = getRandom();
for (i = 0; i < 10; i++)
{
printf("*(p + [%d]) : %d\n", i, *(p + i));
}
return 0;
}
当上面的代码被编译和执行时,会产生下列结果:
1523198053
1187214107
1108300978
430494959
1421301276
930971084
123250484
106932140
1604461820
149169022
*(p + [0]) : 1523198053
*(p + [1]) : 1187214107
*(p + [2]) : 1108300978
*(p + [3]) : 430494959
*(p + [4]) : 1421301276
*(p + [5]) : 930971084
*(p + [6]) : 123250484
*(p + [7]) : 106932140
*(p + [8]) : 1604461820
*(p + [9]) : 149169022
字符串
在 C 语言中,字符串实际上是使用 null 字符终止的一维字符数组。因此,一个以 null 结尾的字符串,包含了组成字符串的字符。
下面的声明和初始化创建了一个 "Hello" 字符串。由于在数组的末尾存储了空字符,所以字符数组的大小比单词 "Hello" 的字符数多一个。
char greeting[6] = {'H', 'e', 'l', 'l', 'o', ''};
依据数组初始化规则,可以把上面的语句写成以下语句:
char greeting[] = "Hello";
其实,不需要把 null 字符放在字符串常量的末尾。C 编译器会在初始化数组时,自动把空字符放在字符串的末尾。
#include <stdio.h>
int main()
{
char greeting[] = {'H', 'e', 'l', 'l', 'o', '\0'};
printf("Greeting message: %s\n", greeting );
return 0;
}
当上面的代码被编译和执行时,会产生下列结果:
Greeting message: Hello
C 中有大量操作字符串的函数:
序号 | 函数 & 目的 |
---|---|
1 | strcpy(s1, s2); 复制字符串 s2 到字符串 s1。 |
2 | strcat(s1, s2); 连接字符串 s2 到字符串 s1 的末尾。 |
3 | strlen(s1); 返回字符串 s1 的长度。 |
4 | strcmp(s1, s2); 如果 s1 和 s2 是相同的,则返回 0;如果 s1<s2 则返回小于 0;如果 s1>s2 则返回大于 0。 |
5 | strchr(s1, ch); 返回一个指针,指向字符串 s1 中字符 ch 的第一次出现的位置。 |
6 | strstr(s1, s2); 返回一个指针,指向字符串 s1 中字符串 s2 的第一次出现的位置。 |
下面的实例使用了上述的一些函数:
#include <stdio.h>
#include <string.h>
int main()
{
char str1[12] = "Hello";
char str2[12] = "World";
char str3[12];
int len;
/* 复制 str1 到 str3 */
strcpy(str3, str1);
printf("strcpy( str3, str1) : %s\n", str3);
/* 连接 str1 和 str2 */
strcat(str1, str2);
printf("strcat( str1, str2): %s\n", str1);
/* 连接后,str1 的总长度 */
len = strlen(str1);
printf("strlen(str1) : %d\n", len);
return 0;
}
当上面的代码被编译和执行时,它会产生下列结果:
strcpy( str3, str1) : Hello
strcat( str1, str2): HelloWorld
strlen(str1) : 10