struct 结构体中 数组和指针
2013-03-27 18:36
246 查看
本文主要介绍在struct 结构体中对数组和指针的操作细节。
我们需要明确两个概念:
a、 初始化:分配内存并写入值。
b、 赋值: 查找内存并写入值。
在上一篇文章有提到数组和指针的初始化和赋值问题,对于数组,可以初始化,但不能对整个数组赋值,而指针,可以初始化也可以赋值。
在结构体中,数组和指针最大的的区别为:数组将信息存在结构体所占有的内存中,而指针是将信息的首地址保存在结构体所占有的内存中,例如:
typedef struct name{
char a[20];
char *p;
}Name;
Name A={“Llilonglin”,“Llilonglin”};
结构体对象A中的数组会将字符串常量“Lilonglin”COPY到A的存储内存中,而A中的指针只保存字符串常量在静态常量存储区中的首地址。
在结构体中对数组的初始化和赋值有以下需要注意:
一、赋值
例如 定义结构体对象
Name A;
在使用时,编译器将会为该结构体分配内存空间,但为对结构对象A的变量初始化。 此时只能通过赋值操作来写入值。在对数组a[10]的赋值时应谨慎,例如:
A. A.a[10]=”Lilonglin”, gcc将给出警告 :“赋值时将指针赋给整数,未作类型转换”,该警告主要由两个原因引起:1、 “.”结构体成员运算符的作用是访问结构体中个成员,该处操作的是结构体变量A中数组的第10个元素,虽然该下标已经越界;2、“Lilonglin”在此处编译器理解为一个常指针,指针是不能直接赋值给字符变量的。
B. A.a=“Lilonglin”,gcc将会提示错误:赋值时,类型不兼容。 在定义申明完数组后数组名具有常量特性,表示数组存储空间的开始地址,而C语言中不能对常量赋值。
C. 根据数组的特性,如果需要得到对数组的正确赋值,则需要对数组的每个元素进行对应赋值。在此不再举例。
二、初始化
在结构体初始化时,用字符串对数组的初始化也需要有注意的地方,例如:
A、 Name A={.a=”Lilonglin”} //OK
B、 1:Name A={.a[10]=”Lilonglin”} //error gcc提示:初始化数组索引越界。
2:Name A={.a[9]=”Lilonglin”} //right printf(“%s”,A.a) 得到“Lilonglin”
3:Name A={.a[1]=”Lilonglin”} // right printf(“%s”,A.a) 得到“Lilonglin”
为什么在1中,指定初始化用a【10】时,gcc会提示越界呢。 在编译的过程中,在语法扫错阶段GCC的对数组边界检查时,发现了该错误,从而给出了提示,在VC下则不会,在此不得不佩服GCC的严谨。
从2和3我们可以看到当使用不同的下标时对数组的初始化完全没有影响,
这不得不怀疑在结构体中,用字符串对数组的初始化时只与数组名有关,因为数组名具有指针属性,之后数组的各个元素被初始化,读者可以打印某个数组元素试试。
此处只讨论了用字符串初始化的情况,对非字符串时指定初始化时,下标将起作用,大家可以试一试
我们需要明确两个概念:
a、 初始化:分配内存并写入值。
b、 赋值: 查找内存并写入值。
在上一篇文章有提到数组和指针的初始化和赋值问题,对于数组,可以初始化,但不能对整个数组赋值,而指针,可以初始化也可以赋值。
在结构体中,数组和指针最大的的区别为:数组将信息存在结构体所占有的内存中,而指针是将信息的首地址保存在结构体所占有的内存中,例如:
typedef struct name{
char a[20];
char *p;
}Name;
Name A={“Llilonglin”,“Llilonglin”};
结构体对象A中的数组会将字符串常量“Lilonglin”COPY到A的存储内存中,而A中的指针只保存字符串常量在静态常量存储区中的首地址。
在结构体中对数组的初始化和赋值有以下需要注意:
一、赋值
例如 定义结构体对象
Name A;
在使用时,编译器将会为该结构体分配内存空间,但为对结构对象A的变量初始化。 此时只能通过赋值操作来写入值。在对数组a[10]的赋值时应谨慎,例如:
A. A.a[10]=”Lilonglin”, gcc将给出警告 :“赋值时将指针赋给整数,未作类型转换”,该警告主要由两个原因引起:1、 “.”结构体成员运算符的作用是访问结构体中个成员,该处操作的是结构体变量A中数组的第10个元素,虽然该下标已经越界;2、“Lilonglin”在此处编译器理解为一个常指针,指针是不能直接赋值给字符变量的。
B. A.a=“Lilonglin”,gcc将会提示错误:赋值时,类型不兼容。 在定义申明完数组后数组名具有常量特性,表示数组存储空间的开始地址,而C语言中不能对常量赋值。
C. 根据数组的特性,如果需要得到对数组的正确赋值,则需要对数组的每个元素进行对应赋值。在此不再举例。
二、初始化
在结构体初始化时,用字符串对数组的初始化也需要有注意的地方,例如:
A、 Name A={.a=”Lilonglin”} //OK
B、 1:Name A={.a[10]=”Lilonglin”} //error gcc提示:初始化数组索引越界。
2:Name A={.a[9]=”Lilonglin”} //right printf(“%s”,A.a) 得到“Lilonglin”
3:Name A={.a[1]=”Lilonglin”} // right printf(“%s”,A.a) 得到“Lilonglin”
为什么在1中,指定初始化用a【10】时,gcc会提示越界呢。 在编译的过程中,在语法扫错阶段GCC的对数组边界检查时,发现了该错误,从而给出了提示,在VC下则不会,在此不得不佩服GCC的严谨。
从2和3我们可以看到当使用不同的下标时对数组的初始化完全没有影响,
这不得不怀疑在结构体中,用字符串对数组的初始化时只与数组名有关,因为数组名具有指针属性,之后数组的各个元素被初始化,读者可以打印某个数组元素试试。
此处只讨论了用字符串初始化的情况,对非字符串时指定初始化时,下标将起作用,大家可以试一试
相关文章推荐
- struct 结构体中 数组和指针
- struct 结构体中对数组和指针的操作细节
- sizeof - 指针,数组,变量,结构体字节对齐-计算
- 结构体 数组 指针
- *指针_函数指针、指针控制数组、链表(结构体指针)
- C语言之_指针数组、结构体、动态内存分配
- java 调用dll的 指针类型结构体及指针数组类型
- C语言之 数组 指针 结构体
- 指针与数组、函数、结构体等之间相关问题
- c# 调用 c++ dll 参数为结构体数组指针
- C语言结构体里的成员数组和指针
- 指向结构体的指针数组,应用
- 结构体指针和结构体数组
- C++第八周mooc在线测评—第8周 按址操作(2)——指针与数组、字符串、结构体,动态数组
- 实验名称: C++数组、指针、结构体的使用
- 20150418多线程、指针与数组、结构体
- C语言结构体里的成员数组和指针
- mfc结构体指针、结构体数组指针
- 读陈浩的《C语言结构体里的成员数组和指针》总结,零长度数组
- C#调用c++Dll 结构体数组指针的问题