C语言->实验室->指针数组
一 分析
讨论指针数组要从三个层面来考虑:
1)指针数组本身是什么
2)指针数组作为参数时的表现
3)指针数组作为返回值时的表现
二 指针数组是什么
1)指针数组--指针的集合
数组是若干元素的集合,那么指针数组就是若干个指针的集合,这个集合内的所有元素都是独立的指针。
2)定义一个指针数组
char* sChar[10];
这里定义了一个指针数组,‘int*’表明其数据类型为int型指针,‘[10]’表明这个集合有10个指针。
3)试用
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/types.h> int main() { char* argList[10]; char* sChar = "1234567"; int i; for(i = 0;i<10;i++) { argList[i] = (char*)malloc(sizeof(char)*100); memset(argList[i],'\0',100); strcpy(argList[i],"1234567890"); } for(i = 0;i<10;i++) { printf("%s\n",argList[i]); } for(i = 0;i<10;i++) { free(argList[i]); } return 0; }
输出:
1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890
在上面的例子中,我们可以简单的将指针数组当做一个指针的集合,数组内所有元素都是独立的指针。
三 指针数组作为参数
1)常规应用
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/types.h> int main() { char* argList[10]; int i; for(i = 0;i<10;i++) { argList[i] = (char*)malloc(sizeof(char)*100); memset(argList[i],'\0',100); strcpy(argList[i],"1234567890"); } DataPrint(argList); for(i = 0;i<10;i++) { free(argList[i]); } return 0; } int DataPrint(char* argList[10]) { int i; for(i = 0;i<10;i++) { printf("%s\n",argList[i]); } }
上面的代码中,我们在主函数中为指针数组分配了内存和值,将其作为参数传递给DataPrint函数,在DataPrint函数中将指针数组的值打印出来,如下:
1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890
2)指针数组中每一个元素都是指针
指针数组中的每一个元素都能当做单独的指针来使用,其特性我们就不多说了。
3)指针数组作为参数传递时,传递的是地址
对于非数组参数,在作为参数进行传递时是将其值传递给了函数,而不是该变量本身,例如:
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/types.h> int main() { int a=1; fun(a); } int fun(int b) { b=3; return 0; }
上面的代码中,b的值一开始由a变量传递过来为1,然后在fun函数中被重新赋值为3.整个过程中,a变量的值都是1。
而数组作为参数进行传递时,考虑到数组内数据量可能很大,所以不会将数组的值传递下去,而是传递该数组的首地址,这样的传递方式就会参数一些有趣的现象。不过在此之前,我们先来看看数组以及指针数组是怎么组成的。
a)定义一个数组
int A[10] = {0,1,2,3,4,5,6,7,8,9};
b)将这个数组作为参数传递
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/types.h> int main() { int A[10] = {0,1,2,3,4,5,6,7,8,9}; printf("A[0]:%u\n",A[0]); fun(A); printf("A[0]:%u\n",A[0]); return 0; } int fun(int B[10]) { B[0]=10; return 0; }
在fun函数中,因为数组传递时传递的是地址而非值,于是B数组:
可以看到,B数组内所有元素在内存中的地址与A数组一致,那么我们改变B数组的值也会间接地改变了A数组的值
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/types.h> int main() { int A[10] = {0,1,2,3,4,5,6,7,8,9}; printf("A[0]:%u\n",A[0]); fun(A); printf("A[0]:%u\n",A[0]); return 0; } int fun(int B[10]) { B[0]=10; return 0; }
输出
A[0]:0 A[0]:10
可以看到,A[0]的值在调用fun函数后发生了改变,这是因为数组将地址而不是值传递给了fun函数,在这种情况下,我们可以简单的认为B=A。
c)定义一个指针数组
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/types.h> int main() { char* argList[10]; int i; for(i = 0;i<10;i++) { argList[i] = (char*)malloc(sizeof(char)*100); memset(argList[i],'\0',100); strcpy(argList[i],"1234567890"); } }
此时argList在内存中表现为
d)将指针数组作为参数传递
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/types.h> int main() { char* argList[10]; int i; for(i = 0;i<10;i++) { argList[i] = (char*)malloc(sizeof(char)*100); memset(argList[i],'\0',100); strcpy(argList[i],"1234567890"); } DataChange(argList); for(i = 0;i<10;i++) { printf("%s\n",argList[i]); } return 0; } int DataChange(char* argList[10]) { int i; for(i = 0;i<10;i++) { argList[i]++; } }
在上面的代码中,我们在DataChange函数内执行了argList[i]++,那么这一语句具体产生了什么效果?argList[i]表明的是argList的第i个元素,其本质是一个指针,该值加一表明该指针元素指向的地址值加一,所以现在argList的内存表现为:
argList[0]++使得ABC00中的XX00值加一,跳过了0值,所以最后输出为
234567890 234567890 234567890 234567890 234567890 234567890 234567890 234567890 234567890 234567890