#include <stdio.h>
typedef struct {
int num;
} Node;
void f1(Node *p) {
p->num = 4300;
};
void f2(Node &p) {
p.num = 200;
}
void f3(Node p) {
p.num = 300;
};
int main()
{
Node n = {
-1
};
f1(&n);
printf("%d\n", n.num);
f2(n);
printf("%d\n", n.num);
f3(n);
printf("%d\n", n.num);
Node stu[3] = {
{11},
{111},
{1111}
};
printf("%d\n", (stu+2)->num);
return 0;
}
f1可以改变结构体原来的值
f2声明会报错,如果想把&符号作为形参,可以将.c文件改成.cpp文件。&p可以获取形参的地址。f2同样可以改变结构体原来的值
f3传值不会改变结构体原来的值
对于结构体数组,可以通过(array+index)->data的方式获取指定索引位置的属性值,数组名本身就是指向第一个元素的指针,所以array+index和*(p+index)是一样的。(array+index)->data等价于*(p+index)->data。
在使用结构体和数组时,如果使用指针p指向他们,写法不同:
结构体: int *p; p = &n;
数组: int *p; p = stu;
同样的,如果定义的函数是void swap(int *p);这种格式,传结构体调用格式为swap(&n),传数组调用格式为swap(stu)。
如果函数是void swap(int &p);,传结构体调用格式为swap(n),相当于调用时执行了p = &n。
传数组格式swap(stu),相当于p=&stu,这样是错误的。此时void swap(int &p)和void swap(int *p)的区别就是array和&array的区别:
- array+1输出的结果中地址值相较于array增加了4个字节(假设数组里是int类型,int类型的一个变量占四个字节)。
- &array+1输出的结果中地址值相较于&array增加了20个字节(0x14 bytes),假设array里有有5个int元素。
通过这个结果可以推断出:
“ array ”是“指向 array 的第一个元素的指针”,而“ &array ”是“指向 拥有5 个 int 元素的整个数组的指针”。
所以函数的参数是数组时,通常不会声明void swap(int &p);,使用数组作为参数有三种方法:
- void swap(int *p);
- void swap(int arr[10]);
- void swap(int arr);
总结下来就是数组比较特殊,数组名本身就代表了地址不需要前面加&,而int类型、结构体等类型都是需要加&传地址。
下面看一个通过传数组名操作数组的例子:
#include <stdio.h>
void sort1(int arr[])
{
arr[0] = 999;
}
char *sort2(int *arr)
{
arr[0] = -3;
*(arr + 1) = -111;
return "";
}
int main()
{
int a[] = {1, 21, 33, 44, 55};
sort1(a);
printf("sort1:%d\n", *a);
sort2(a);
int i = 0;
while(i < 5) {
printf("sort2:%d\n", *(a+i));
i++;
}
return 0;
}
sort1函数和sort2函数都可以改变实参数组原来的数据,读取数组的值可以用*(a+i),a[i],*(p+i),p[i]这几种方式:
更多内容参考:C 结构体 | 菜鸟教程
强烈推荐C primer plus这本书,代码都是可以运行的,而且最后还补充了数据结构的内容。