为什么我的char*数组中的元素是两个字节而不是四个字节
我是C语言的新手,所以如果这个问题很琐碎,请原谅我。我正在尝试反转一个字符串,在 我的箱子是字母a、b、c、d。我将字符放在char*数组中,并声明一个缓冲区 它将按相反的顺序保存字符,d,c,b,a。我使用 指针算法,但据我所知,char*数组中的每个元素都是4字节,因此当我执行以下操作时:为什么我的char*数组中的元素是两个字节而不是四个字节,c,C,我是C语言的新手,所以如果这个问题很琐碎,请原谅我。我正在尝试反转一个字符串,在 我的箱子是字母a、b、c、d。我将字符放在char*数组中,并声明一个缓冲区 它将按相反的顺序保存字符,d,c,b,a。我使用 指针算法,但据我所知,char*数组中的每个元素都是4字节,因此当我执行以下操作时:buffer[I]=*(char**)字母+4我应该指向 数组中的第二个元素。它不是指向第二个元素,而是指向第三个元素。经过进一步的检查,我认为如果我将基指针增加2 每次我都会得到想要的结果。这是否意味着数
buffer[I]=*(char**)字母+4代码>我应该指向
数组中的第二个元素。它不是指向第二个元素,而是指向第三个元素。经过进一步的检查,我认为如果我将基指针增加2
每次我都会得到想要的结果。这是否意味着数组中的每个元素
是2字节而不是4字节吗?以下是我的代码的其余部分:
#include <stdio.h>
int main(void)
{
char *letters[] = {"a","b","c","d"};
char *buffer[4];
int i, add = 6;
for( i = 0 ; i < 4 ; i++ )
{
buffer[i] = *(char**)letters + add;
add -= 2;
}
printf("The alphabet: ");
for(i = 0; i < 4; i++)
{
printf("%s",letters[i]);
}
printf("\n");
printf("The alphabet in reverse: ");
for(i = 0; i < 4; i++)
{
printf("%s",buffer[i]);
}
printf("\n");
}
#包括
内部主(空)
{
字符*字母[]={“a”、“b”、“c”、“d”};
字符*缓冲区[4];
整数i,相加=6;
对于(i=0;i<4;i++)
{
缓冲区[i]=*(字符**)字母+加法;
加-=2;
}
printf(“字母表:”);
对于(i=0;i<4;i++)
{
printf(“%s”,字母[i]);
}
printf(“\n”);
printf(“相反的字母:”);
对于(i=0;i<4;i++)
{
printf(“%s”,缓冲区[i]);
}
printf(“\n”);
}
您没有创建字符数组:您创建的是字符串数组,即指向字符数组的指针数组。当然,我不会为您重写整个程序,但我将首先为您的主数据结构提供两种可能的正确声明:
char letters[] = {'a','b','c','d, 0};
char * letters = "abcd";
其中任何一个都声明了一个由五个字符组成的数组:a、b、c、d后跟0,这是c中字符串的传统结尾。您不是在创建一个字符数组:您正在创建一个字符串数组,即指向字符数组的指针数组。当然,我不会为您重写整个程序,但我将首先为您的主数据结构提供两种可能的正确声明:
char letters[] = {'a','b','c','d, 0};
char * letters = "abcd";
这其中任何一个都声明了一个由五个字符组成的数组:a、b、c、d后跟0,这是c中字符串的传统结尾。另一件事:与其对事物的大小进行假设,不如使用语言来告诉您。例如:
char *my_array[] = { "foo" , "bar" , "baz" , "bat" , } ;
// the size of an element of my_array
size_t my_array_element_size = sizeof(my_array[0]) ;
size_t alt_element_size = size(*my_array) ; // arrays are pointers under the hood
// the number of elements in my_array
size_t my_array_element_cnt = sizeof(my_array) / sizeof(*myarray ;
// the size of a char
size_t char_size = sizeof(*(my_array[0])) ; // size of a char
另一件事:了解您的数据结构(如上所述)。您谈论的是字符,但您的数据结构谈论的是字符串。你的声明:
char *letters[] = {"a","b","c","d"};
char *buffer[4];
按如下方式进行分析:
letters
是指向char的指针数组(恰好是以nul结尾的C样式字符串),它由4个元素初始化
- 与
字母
类似,缓冲区
是一个由4个指向char的指针组成的数组,但未初始化
实际上,您没有在任何地方处理单个字符,即使在printf()
语句中也是如此:%s
说明符表示参数是以nul结尾的字符串。相反,您处理的是字符串(即指向char
的指针)及其数组
更简单的方法:
#include <stdio.h>
int main(void)
{
char *letters[] = { "a" , "b" , "c" , "d" , } ;
size_t letter_cnt = size(letters)/sizeof(*letters) ;
char *buffer[sizeof(letters)/sizeof(*letters)] ;
for ( int i=0 , j=letter_cnt ; i < letter_cnt ; ++i )
{
buffer[--j] = letters[i] ;
}
printf("The alphabet: ");
for( int i = 0 ; i < letter_cnt ; ++i )
{
printf("%s",letters[i]);
}
printf("\n");
printf("The alphabet in reverse: ");
for( int i=0 ; i < letter_cnt ; i++ )
{
printf("%s",buffer[i]);
}
printf("\n");
}
#包括
内部主(空)
{
字符*字母[]={“a”、“b”、“c”、“d”、};
大小字母=大小(字母)/sizeof(*字母);
字符*缓冲区[sizeof(字母)/sizeof(*字母)];
对于(int i=0,j=letter_cnt;i
顺便说一句,这是家庭作业吗?另一件事:与其对事物的大小做出假设,不如用语言告诉你。例如:
char *my_array[] = { "foo" , "bar" , "baz" , "bat" , } ;
// the size of an element of my_array
size_t my_array_element_size = sizeof(my_array[0]) ;
size_t alt_element_size = size(*my_array) ; // arrays are pointers under the hood
// the number of elements in my_array
size_t my_array_element_cnt = sizeof(my_array) / sizeof(*myarray ;
// the size of a char
size_t char_size = sizeof(*(my_array[0])) ; // size of a char
另一件事:了解您的数据结构(如上所述)。您谈论的是字符,但您的数据结构谈论的是字符串。你的声明:
char *letters[] = {"a","b","c","d"};
char *buffer[4];
按如下方式进行分析:
letters
是指向char的指针数组(恰好是以nul结尾的C样式字符串),它由4个元素初始化
- 与
字母
类似,缓冲区
是一个由4个指向char的指针组成的数组,但未初始化
实际上,您没有在任何地方处理单个字符,即使在printf()
语句中也是如此:%s
说明符表示参数是以nul结尾的字符串。相反,您处理的是字符串(即指向char
的指针)及其数组
更简单的方法:
#include <stdio.h>
int main(void)
{
char *letters[] = { "a" , "b" , "c" , "d" , } ;
size_t letter_cnt = size(letters)/sizeof(*letters) ;
char *buffer[sizeof(letters)/sizeof(*letters)] ;
for ( int i=0 , j=letter_cnt ; i < letter_cnt ; ++i )
{
buffer[--j] = letters[i] ;
}
printf("The alphabet: ");
for( int i = 0 ; i < letter_cnt ; ++i )
{
printf("%s",letters[i]);
}
printf("\n");
printf("The alphabet in reverse: ");
for( int i=0 ; i < letter_cnt ; i++ )
{
printf("%s",buffer[i]);
}
printf("\n");
}
#包括
内部主(空)
{
字符*字母[]={“a”、“b”、“c”、“d”、};
大小字母=大小(字母)/sizeof(*字母);
字符*缓冲区[sizeof(字母)/sizeof(*字母)];
对于(int i=0,j=letter_cnt;i
顺便说一句,这是作业吗?这是运算符优先的情况。使用buffer[i]=*(char**)字母+add时
,在转换之前的*
在+
之前执行,使此代码相当于(*(char**)字母)+add代码>。第一部分相当于数组中第一个元素的地址,字符串“a”。由于使用字符串常量会自动添加一个空字节,因此指向'a\0'
。编译器恰好将所有四个字符串紧跟在一起放入内存中,因此,如果超过该字符串的末尾,则会流入下一个字符串。添加到指针时,您将在以下字符数组中移动:'a\0b\0c\0d\0'
。请注意,每个字符在最后一个字符后有2个字节。因为这是唯一正确的,因为编译器直接放置了4个字符串