指针数组

指向指针的数组

Posted by Dandan on August 3, 2018

指针数组—-指向指针的数组

运算符优先级

优先级 运算符 名称或含义
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,避免了数组越界的问题

数组位置存储

编译器在决定一个变量的存储位置时,通常有一下的考虑因素:

  • 定义顺序,一般按照定义顺序
  • 对其要求,计算机的体系结构对特定的数据有对其要求,以特定的字节对齐,在数据结构中颇为明显
  • 优化,编译器自动优化 可能会改变存储位置
  • 内存布局:堆栈、数据段等