一维数组名也是一个地址,即指针,只不过数组名是一个常量指针,常量指针即不能修改该指针的值!所以看字符数组的赋值与字符指针的赋值就明白了!
void main() {
int a[5] = { 0,1,2,3,4 };
//a++;a--这些操作都是错误的!
char buf[32] = "hello world"; //这是可以的,hello world以字符的形式拼接成的,存储在栈区
char buf1[32];
//buf1 = "hello world"; // 这是不可以的,hello world是字符常量在支付常量区,这样赋值,修改的a的指向,是不允许的
//那么这时候给buf1赋值,需通过strcpy来完成;
strcpy(buf1, "hello world");
buf1[0] = 'b';//可以修改
char *ptr = NULL;
ptr = "hello world"; //这是可以的,ptr指向字符常量区的地址,ptr的值可以修改
//ptr[0] = 'b';不允许的,不能修改字符常量区中的内容;
system("pause");
}
其实理解了内存四区和数组名的含义,上面的代码就很好理解!
1.一维数组做函数参数
一维数组做函数参数,被调函数的参数怎么定义呢?最简单的方式,如果不知道怎么写参数,来最直接的!
void change(int a[5]) { //直接定义一个数组来做参数
int i = 0;
for (i = 0; i < 5; i++) {
a[i] = i + 10;
}
}
void main() {
int a[5] = { 0,1,2,3,4 };
int i = 0;
change(a); //传递数组名
for (i = 0; i < 5; i++) {
printf("%d\n", a[i]);
}
system("pause");
}
当然,这种写法如果在公司,会显示你的代码能力很low,对C语言的理解估计还没有入门;利用sizeof看一下被调函数中的形参数组的大小是多少?
void change(int a[5]) { //直接定义一个数组来做参数
int i = 0;
printf("%d\n", sizeof(a)); // 看一下形参这个数组名的大小是多少
for (i = 0; i < 5; i++) {
a[i] = i + 10;
}
}
void main() {
int a[5] = { 0,1,2,3,4 };
int i = 0;
change(a); //传递数组名
for (i = 0; i < 5; i++) {
printf("%d\n", a[i]);
}
system("pause");
}
通过上面代码可以知道,形参数组名的大小为4个字节;也就是说,数组名作为参数,数组名退化成一个指针,那么使用指针来作为被调函数的参数即可!
void change(int *a) { //直接定义一个数组来做参数
int i = 0;
printf("%d\n", sizeof(a)); // 看一下形参这个数组名的大小是多少
for (i = 0; i < 5; i++) {
a[i] = i + 10;
}
}
void main() {
int a[5] = { 0,1,2,3,4 };
int i = 0;
change(a); //传递数组名
for (i = 0; i < 5; i++) {
printf("%d\n", a[i]);
}
system("pause");
}
2.指针数组做函数参数
指针数组也是一个一维数组,只不过数组中的元素是指针罢了,通过数组名即可遍历数组:
void main() {
int a = 10, b = 20, c = 30, d = 40, e = 50;
int *arr[5] = {&a,&b,&c,&d,&e};
int i = 0;
//change(a); //传递数组名
for (i = 0; i < 5; i++) {
printf("%d\n", *arr[i]);//a[i]是数组中的元素,但是元素是地址,想要取出地址中的值,必须是*arr[i];
}
system("pause");
}
指针数组作为函数参数,被调函数的参数该如何定义?由前一章可知,指针数组的数组名相当于一个二级指针!如果对二级指针不熟悉,还是老办法,直接定义一个指针数组来接收实参即可:
void change(int *a[5]) { //直接定义一个数组来做参数
int i = 0;
for (i = 0; i < 5; i++) {
*a[i] = i + 100;
}
}
void main() {
int a = 10, b = 20, c = 30, d = 40, e = 50;
int *arr[5] = {&a,&b,&c,&d,&e};
int i = 0;
change(arr); //传递数组名
for (i = 0; i < 5; i++) {
printf("%d\n", *arr[i]);//a[i]是数组中的元素,但是元素是地址,想要取出地址中的值,必须是*arr[i];
}
system("pause");
}
还是那句话,这样的代码很low,指针数组的数组名相当于一个二级指针,那么使用二级指针来接收实参:
void change(int **a) { //直接定义一个数组来做参数
int i = 0;
for (i = 0; i < 5; i++) {
//a指向指针数组的首地址,a+1指向第二个元素,a+i指向数组的第i个元素,那么*(a+i)就是数组的第i个元素,
//由于数组的元素是指针,所以**(a+i)才是数组的指针元素指向的内存的值;
**(a + i) = i + 1000;
}
}
void main() {
int a = 10, b = 20, c = 30, d = 40, e = 50;
int *arr[5] = {&a,&b,&c,&d,&e};
int i = 0;
change(arr); //传递数组名
for (i = 0; i < 5; i++) {
printf("%d\n", *arr[i]);//a[i]是数组中的元素,但是元素是地址,想要取出地址中的值,必须是*arr[i];
}
system("pause");
}
3.字符指针数组做函数参数
看下面的代码,如果我们想要通过函数调用来修改修改数组其中的某一个元素的值,即假如需要将buf[2]的值修改成“studeng”,该怎么修改?
void main() {
char *buf[] = { "hello","world","welcome","profect" };
char **ptr = buf;
int i = 0;
for (i = 0; i < 4; i++) {
printf("%s\n", *(ptr +i)); //使用二级指针来遍历字符指针数组;
}
system("pause");
}
也就是被调函数的参数该如何定义?先思考一下!
解答之前先回忆一下前面的内容;
char *buf[] = { "hello","world","welcome","profect" }
char *ptr = NULL;
对这个字符指针数组来说,&buf[0]与&buf[1]之间相差几个字节?
ptr与ptr+1相差几个字节?
这个问题搞清楚以后,就知道函数传递该如何定义了
void change(char **ptr) {
//下面的哪行代码是正确的?
//ptr[2] = "student";
//*ptr[2] = "student";
}
void main() {
char *buf[] = { "hello","world","welcome","profect" };
char **ptr = buf;
int i = 0;
change(buf);
for (i = 0; i < 4; i++) {
printf("%s\n", *(ptr +i)); //使用二级指针来遍历字符指针数组;
}
system("pause");
}
总结:
由上面可知,指针数组名相当于一个二级指针,那么在定义被调函数的参数的时候,需要使用二级指针(type **ptr)来接收函数名,这时候二级指针就相当于是函数名了,ptr+i指向数组的第i个元素,
*(ptr+i)就是数组的第i个元素的值,由于指针数组的元素就是一个指针,所以**(ptr+i)才是这个数组的指针元素所指向的内存中的值!