指针数组—-指向指针的数组
运算符优先级
优先级 | 运算符 | 名称或含义 |
---|---|---|
1 | [] | 数组下标 |
1 | () | 圆括号 |
1 | ./-> | 成员选择 |
2 | - | |
2 | ++/– | |
2 | */& | |
2 | !/~ |
const char * gr600c_physic_ports[] = {“eth0”, “eth1”, “eth2”, “eth3”, “eth4”, “eth5”, ‘\0’};
根据元素府优先级,[]优先级高于 *,所以这是一个数组。上述为指针数组
- int (a)[3] –>是数组指针,()的优先级最高,a是指针,所以是数组指针。
数组指针和指针数组的区别
数组指针一般包含() 指针数组不包含()
程序例子
例子1
#include <stdio.h>
int main(){
const char * gr600_physic_ports[] = {"eth0.1", "eth0.2"};
const char * gr600c_physic_ports[] = {"eth0", "eth1", "eth2", "eth3", "eth4", "eth5"};
int j = 0;
while (gr600c_physic_ports[j] != NULL ) {
printf("Port: %s\n", gr600c_physic_ports[j]);
j++;
}
}
运算结果:
Port: eth0
Port: eth1
Port: eth2
Port: eth3
Port: eth4
Port: eth5
Port:
段错误 (核心已转储)
例子3
#include <stdio.h>
int main(){
char ** point = NULL;
const char * gr600_physic_ports[8] = {"eth0.1", "eth0.2"};
const char * gr600c_physic_ports[] = {"eth0", "eth1", "eth2", "eth3", "eth4", "eth5"};
point = gr600c_physic_ports;
int j = 0;
while (point[j] != NULL ) {
printf("Port: %s\n", point[j]);
printf("Port: %s\n", gr600c_physic_ports[j]);
j++;
}
}
运算结果:
Port: eth0
Port: eth0
Port: eth1
Port: eth1
Port: eth2
Port: eth2
Port: eth3
Port: eth3
Port: eth4
Port: eth4
Port: eth5
Port: eth5
Port: eth0.1
Port: eth0.1
Port: eth0.2
Port: eth0.2
例子2
#include <stdio.h>
int main(){
const char * gr600_physic_ports[] = {"eth0.1", "eth0.2"};
const char * gr600c_physic_ports[] = {"eth0", "eth1", "eth2", "eth3", "eth4", "eth5",NULL};
int j = 0;
while (gr600c_physic_ports[j] != NULL ) {
printf("Port: %s\n", gr600c_physic_ports[j]);
j++;
}
}
运算结果:
Port: eth0
Port: eth1
Port: eth2
Port: eth3
Port: eth4
Port: eth5
结果以及结论
- 为什么上述三个例子的结果不一样,因为例子1 、2中的gr600c_physic_ports数组是没有结束标志;
- C程序中的数组名实际上指向的是起第一个元素的指针,所以在访问数组时,程序只是访问该数组的第一个元素的地址。如果
gr600_physic_ports
数组的地址在gr600c_physic_ports
数组之后,并且它们之间没有 NULL 值来标记其结束,则在gr600c_physic_ports
数组遍历结束之前,程序可能会遍历gr600_physic_ports
数组的值。 - 需要在 gr600c_physic_ports 数组的最后一个元素之后添加一个 NULL 值来明确其结束,以避免遍历到其他数组的值。
或者通过其他方法(获取数组个数)来解决:
const char * gr600c_physic_ports[] = {"eth0", "eth1", "eth2", "eth3", "eth4", "eth5"};
int num_ports = sizeof(gr600c_physic_ports) / sizeof(gr600c_physic_ports[0]);
for (int j = 0; j < num_ports; j++) {
printf("Port: %s\n", gr600c_physic_ports[j]);
}
该方法不需要后加NULL,避免了数组越界的问题
数组位置存储
编译器在决定一个变量的存储位置时,通常有一下的考虑因素:
- 定义顺序,一般按照定义顺序
- 对其要求,计算机的体系结构对特定的数据有对其要求,以特定的字节对齐,在数据结构中颇为明显
- 优化,编译器自动优化 可能会改变存储位置
- 内存布局:堆栈、数据段等