user-0 提问: char *name[] = { "Follow me", "BASIC", "Great Wall" };

回复:
user: user-1
content: char *name[] = { "Follow me", "BASIC", "Great Wall" }; 要看编译器怎么处理，这样的字符指针数组一般是，存放3个整形指针，每个指针指向存放字符串的地址，字符串可能不连续在一起，一般可能是连续在一起（每个字符串后至少会有一个'\0'，也可能编译器多加‘\0'),所以地址差值不一定等于长度加一个0的位置

user: user-2
content: 用我惯用的方式表达，就是张三的鼻子到肚脐的距离是有意义的，但是张三的鼻子到李四的耳朵的距离在我们讨论的范畴下是没有意义的。

user: user-2
content: 四老师的解释是站在编译器开发者的角度，解释了一下编译器对静态地址的分配。 而站在程序猿的立场，你需要知道，那三个用于初始化指针数组的字符串，互相之间是没有法定关系的。 我的意思是，那三个字符串并不属于同一个数组什么的，是你把它们的地址组织成了一个数组，而已。 不是同一数组的元素地址之间求差无意义。 所以你那个差值，固然描述了你的机器上你的系统上这一时刻的事实，但它（差值）是个C范畴下的无意义的量。

user: user-0
content: 懂意思了，谢谢～

user: user-3
content: 刚在vs2019上测试了一下, 指针数组的各字符串元素并不一定要连续存储, 元素间的空白存储单元也是随机的.

user: user-4
content: 我的理解，对齐到4的倍数。

user: user-0
content: 看了你的，发现明白了什么意思了。但是字符存储的时候一个字符不是占用1个字节吗？

user: user-4
content: 将地址对齐到4的倍数是为了让CPU读的时候不因为地址不是4的倍数分两次读或抛出异常。

user: user-4
content: //#pragma warning(disable:4996) //开头加这句或项目、属性、配置属性、C/C++、预处理器、预处理器定义中添加“_CRT_SECURE_NO_WARNINGS” #include<stdio.h> #include<string.h> void HexDump(char *buf,int len,int addr) {     int i,j,k;     char binstr[80];      for (i=0;i<len;i++) {         if (0==(i%16)) {             sprintf(binstr,"%08x -",i+addr);             sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);         } else if (15==(i%16)) {             sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);             sprintf(binstr,"%s  ",binstr);             for (j=i-15;j<=i;j++) {                 sprintf(binstr,"%s%c",binstr,('!'<buf[j]&&buf[j]<='~')?buf[j]:'.');             }             printf("%s\n",binstr);         } else {             sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);         }     }     if (0!=(i%16)) {         k=16-(i%16);         for (j=0;j<k;j++) {             sprintf(binstr,"%s   ",binstr);         }         sprintf(binstr,"%s  ",binstr);         k=16-k;         for (j=i-k;j<i;j++) {             sprintf(binstr,"%s%c",binstr,('!'<buf[j]&&buf[j]<='~')?buf[j]:'.');         }         printf("%s\n",binstr);     } } int main(void) {     char *name[] = { "Follow me", "BASIC", "Great Wall" };     printf("sizeof(name[0]):%d\n", sizeof(name[0]));     for (int i = 0; i < 3; i++)     {         printf("name[%d]:0x%p strlen(name[%d]):%d\n",i,name[i],i,strlen(name[i]));     }     HexDump((char *)(name[2]),48,(int)(name[0]));     return 0; } //sizeof(name[0]):4 //name[0]:0x00403074 strlen(name[0]):9 //name[1]:0x0040306C strlen(name[1]):5 //name[2]:0x00403060 strlen(name[2]):10 //00403074 - 47 72 65 61 74 20 57 61 6c 6c 00 00 42 41 53 49  Great.Wall..BASI //00403084 - 43 00 00 00 46 6f 6c 6c 6f 77 20 6d 65 00 00 00  C...Follow.me... //00403094 - 73 69 7a 65 6f 66 28 6e 61 6d 65 5b 30 5d 29 3a  sizeof(name[0]):  VC6 Release

user: user-4
content: #pragma warning(disable:4996) //开头加这句或项目、属性、配置属性、C/C++、预处理器、预处理器定义中添加“_CRT_SECURE_NO_WARNINGS” #include<stdio.h> #include<string.h> void HexDump(char *buf,int len,int addr) {     int i,j,k;     char binstr[80];      for (i=0;i<len;i++) {         if (0==(i%16)) {             sprintf(binstr,"%08x -",i+addr);             sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);         } else if (15==(i%16)) {             sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);             sprintf(binstr,"%s  ",binstr);             for (j=i-15;j<=i;j++) {                 sprintf(binstr,"%s%c",binstr,('!'<buf[j]&&buf[j]<='~')?buf[j]:'.');             }             printf("%s\n",binstr);         } else {             sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);         }     }     if (0!=(i%16)) {         k=16-(i%16);         for (j=0;j<k;j++) {             sprintf(binstr,"%s   ",binstr);         }         sprintf(binstr,"%s  ",binstr);         k=16-k;         for (j=i-k;j<i;j++) {             sprintf(binstr,"%s%c",binstr,('!'<buf[j]&&buf[j]<='~')?buf[j]:'.');         }         printf("%s\n",binstr);     } } int main(void) {     char *name[] = { "Follow me", "BASIC", "Great Wall" };     printf("sizeof(name[0]):%d\n", sizeof(name[0]));     for (int i = 0; i < 3; i++)     {         printf("name[%d]:0x%p strlen(name[%d]):%d\n",i,name[i],i,strlen(name[i]));     }     HexDump((char *)(name[0]),48,(int)(name[0]));     return 0; } //sizeof(name[0]):4 //name[0]:0x003E2134 strlen(name[0]):9 //name[1]:0x003E2140 strlen(name[1]):5 //name[2]:0x003E2148 strlen(name[2]):10 //003e2134 - 46 6f 6c 6c 6f 77 20 6d 65 00 00 00 42 41 53 49  Follow.me...BASI //003e2144 - 43 00 00 00 47 72 65 61 74 20 57 61 6c 6c 00 00  C...Great.Wall.. //003e2154 - 73 69 7a 65 6f 66 28 6e 61 6d 65 5b 30 5d 29 3a  sizeof(name[0]):   VS2015 release