结构体的一些问题

1.结构体名不是结构体的地址。

数组名是数组的首地址,函数名是函数的地址,但是,结构体名不是结构体的地址!记得曾经犯过这个错误,这次又犯了。

以下这个例子可以很好的证明这一点:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <iostream> 
using namespace std; 
 
typedef struct A{ 
    char *a; 
    int b; 
}A; 
 
int main() 
{ 
    A m={"abc", 5}; 
    printf("&m=%d, m.a=%d, m.b=%d\n",m, m.a, m.b);  //这里有问题 
    return 0; 
 
}

在这个例子中:

输出:4291544 5 4291544(这里有问题了,应该是4291544 4291544 5)

这里传递三个变量到数据缓冲区,分别是m, m.a, m.b。

而输出时,第一个是取4字节,而m是8字节(注意内存对齐问题,虽然这里不明显)。所以,第一个输出只取了m的前四个字节,也就是m.a;而第二个也只去4个字节,即m的后四个字节,也就是m.b;第三个取缓冲区中的m.a。

要输出结构体的地址,和变量一样,要&m.

延伸–内存对齐问题:

1.http://www.cppleyuan.com/viewthread.php?tid=17&highlight=%E5%86%85%E5%AD%98%E5%AF%B9%E9%BD%90

2.http://www.cppleyuan.com/viewthread.php?tid=18&highlight=%E5%86%85%E5%AD%98%E5%AF%B9%E9%BD%90

2.结构体的传输问题。

先看看这个例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// Tanky Woo
// www.WuTianQi.com
#include <iostream> 
#include <string> 
using namespace std; 
 
typedef struct A{ 
    char *a; 
    int b; 
}A; 
 
void fun(A m) 
{ 
    printf("&m=%d, m.a=%d, &m.a=%d, &m.b=%d\n", &m, m.a, &m.a, &m.b); 
} 
 
int main() 
{ 
    A m={"abc", 5}; 
 
    printf("&m=%d, m.a=%d, &m.a=%d, &m.b=%d\n", &m, m.a, &m.a, &m.b); 
    fun(m); 
    return 0; 
}

输出:

&m=1245020, m.a=4291560, &m.a=1245020, &m.b=1245024
&m=1244804, m.a=4291560, &m.a=1244804, &m.b=1244808

通过这个例子可以很好的理解指针的传递。

这里说一点,我们经常说按值传递和按址传递,其实,按址传递也是一种按值传递,只不过比较特殊而已,因为传递的是地址这个值。

看输出结果可以知道,两个a的值相同,但是两个a的地址并不一样。这是因为传递的是地址这个副本。如果你在函数中改变a中存取的值,并不会改变原指针a指向的空间位置。

发布者

Tanky Woo

Tanky Woo,[个人主页:https://tankywoo.com] / [新博客:https://blog.tankywoo.com]

《结构体的一些问题》有45个想法

发表评论

电子邮件地址不会被公开。 必填项已用*标注