这个字符串数组声明对吗?

这个字符串数组声明对吗?const char *mytal[5]{"aaaaaaaaaaaaaaaaaa","bbbbbbbbbbbbbbbbbbbb","ccccccccccccccccc","dddddddddddddddddd","eeeeeeeeeeeeeeeeeeeeeeeee"};
1,*mytal[5]是数组指针还是指针数组啊?
2,mytal应该相当于根地址,对吗?
3,为什么没有声明字符串长度呢?
4,mytal+1是加多少个字节呢?
最新回答
传说甜蜜的味道

2024-11-07 00:38:59

少了个赋值符号,即
const char *mytal[5] ={"aaaaaaaaaaaaaaaaaa","bbbbbbbbbbbbbbbbbbbb","ccccccccccccccccc","dddddddddddddddddd","eeeeeeeeeeeeeeeeeeeeeeeee"};

这样是对的。

1,*mytal[5]是字符串指针数组;
2,对,mytal相当于指针数组的根地址;
3,定义的字符串都是常量,长度在定义时已固定,运行时,自动加载到内存中,不需要指定。
4,mytal+1,跳到指针数组的第二个指针,32位系统下会跳4字节,64位系统下会跳8字节。使用*(mytal+1)时,会返回第二个字符串常量的首地址。
追问
4.1,在32位系统里, mytal和mytal+1间隔4字节。而每个字符可以用比如mytal[0][1]表示吧?那mytal[0]+1又是加多少位呢?字符串那么长可能会有mytal[0]+17 。4字节距离不够吧?还是说字符串地址不是这样排列的。下面这个数组地址是这样排列的吗?
int mytal[2][3]=
{{1,2,3},{3,2,1},};
追答
mytal[0]+1是以char的字节数为单位进行跳转的,mytal+1是以指针地址的存储空间为单位进行跳转的,在32位系统内一个地址的存储空间是4字节,指针数组是一个连续的存放有地址的数组,mytal+1是在这个存放地址的数组中跳转,一次跳4字节
追问
假设mytal[0]有20个字符
并且mytal==mytal[0]
mytal+1是加4字节
mytal[0]+19加19字节
这样第一个字符串就覆盖到第二个字符串mytal[1]里面去了。
追答
一、首先,mytal[0]有20个字符,mytal[0]+19是指向最后一个字符,还没有跳出字符串,当然里面可能只是NULL,即字符串终止符;
二、mytal[0]+20是跳出了mytal[0]指定的字符串存储空间,即越界访问了。至于是访问到mytal[1]还是mytal[2],这是未知的,因为mytal[0]和mytal[1]、mytal[2]指向的存储空间,不一定是首尾相联依次排列的,这要看编译器的编译方式。
三、你追问里又提到了mytal+1是加4字节,这是确定的,因为指针的跳转是以定义指针的类型来决定,如:char *p是字符型指针,跳转以字符长度为单位,mytal[0]就是字符型指针;int *p是整型指针,跳转以整型长度为单位;而指针数组首地址,即指向地址数组的指针,也称指向指针的指针,是以地址长度为单位跳转,mytal就是指针数组首地址的指针。
再细化一下,指针就是汇编里寻址用的寄存器,寄存器保存的地址值,指明了数据存放的位置。指针的指针,说明数据存放位置里存放的是地址;字符串指针,数据存放位置里保存的数据就是字符,指针跳转就是对寄存器的值进行加减,加减数值的大小,由数据的类型来决定。

补充:
下面说mytal相当于 const char * mytal[0];这是不对的,应该说:mytal相当于&mytal[0]或者*mytal相当于mytal[0]。
指针不需要存储空间这也不对,指针一般存储在代码段或数据段,也需要存储空间。
追问
mytal+1就是mytal[1]
加2就是mytal[2]
加3就是mytal[3]
这样不就是说它们是间隔4字节的连续数组吗?如果mytal[1]长度大于4字节这个间隔,这样就覆盖了mytal[2]了
不好意思,确实很难理解这个数组和指针,打扰了
追答

在字符串指针数组中,指针数组和字符串是存储在不同的两块内存区域

而如果定义成:

const char mytal[5][30]={......};

char mytal[5]就是字符串数组,每个字符串最长都是30.多数情况下每个字符串都是首尾相连依次存储在一起的,这时mytal[1]和mytal[2]间隔是30个字符。


给你一段代码,看一下地址偏移量就知道真像了:

#include <stdio.h>
#include <stdlib.h>

const char a[5][30]={"aaaaaaaaaaaaaaaaaa","bbbbbbbbbbbbbbbbbbbb","ccccccccccccccccc","dddddddddddddddddd","eeeeeeeeeeeeeeeeeeeeeeeee"};
const char *b[5]={"aaaaaaaaaaaaaaaaaa","bbbbbbbbbbbbbbbbbbbb","ccccccccccccccccc","dddddddddddddddddd","eeeeeeeeeeeeeeeeeeeeeeeee"};

int main()
{
    int i;
    
    printf ( "a指针地址\tb指针地址\n");
    for ( i = 0; i < 5; i++ )
    {
        printf ( " %p\t %p\n", (a+i),(b+i));
    }

    long lAddr0,lAddr1;
    lAddr0=(long)a;
    lAddr1=(long)(a+1);
    printf ( "\n字符串数组a,相邻指针偏移量\n");
    printf ( "%p\t-\t%p\t=\t%d\n", a,(a+1),lAddr1-lAddr0);

    lAddr0=(long)b;
    lAddr1=(long)(b+1);
    printf ( "\n字符串指针数组b,相邻指针偏移量\n");
    printf ( "%p\t-\t%p\t=\t%d\n", b,(b+1),lAddr1-lAddr0);
 
    system ( "pause" );
    return 0;
}
追问
嗯,知道了,非常感谢!
舞尽桃花

2024-11-07 00:57:57

第一个问题:这是5个字符串指针
第二个问题 :mytal相当于 const char * mytal[0]
第三个问题 :指针是存储字符的开始位址并不需要存储空间
第四个问题 :mytal+1是下一个指针的起始位址