我们如何返回最后一个字符串的索引或最后一个字符串的基地址?

时间:2015-09-29 19:29:37

标签: c arrays string

 char *str[]={"we", "will", "teach", "you"};
 int count=0;i,len,m;

sizeof(str)应返回值18,而在codeblocks中返回值32。 如果它正确地返回字符串的长度,知道这个字符数组存储在连续的内存位置这一事实,我们可以计算当我们遍历数组时出现“\ 0”的次数。

这个值会给我们最后一个字符串的索引。 我尝试了以下方式:

int len=sizeof(str);

m=str[0]; //assign the base address of 1st string
for(i=0;i<len;i++)
{
   if(*(m+i)=="\0") //compare the value at memory location with null
   count++;
 }
 printf("%d", count);

如果有人能够让我了解我的方法是否正确,或者是其他解决方案。 基本上想要找到最后一个字符串的索引,或者当数组中的字符串数量无法计算时,存在的字符串数。

5 个答案:

答案 0 :(得分:4)

 char *str[]={"we", "will", "teach", "you"};
 int count=0;i,len,m;
     

sizeof(str)返回值18,而返回值32   码块。

如果您的编译器行为正确,则

18是不可能的。这是因为sizeof的结果与所有字符串的总长度无关。它返回char*的大小,该大小与实现有关,乘以数组中的元素数。 18不能除以4。

尝试一些不那么混乱的东西,比如short arr[] = { 1, 2, 3, 4, 5 };。它在我的机器上返回10,因为sizeof(short)在我的机器上是2而且数组有5个元素,2 * 5 = 10

  

知道这个字符数组是连续存储的   记忆位置

不保证这样存储。事实上,根本没有。单个字符串文字位于连续的内存中,指向这些文字的指针也是连续的。就这样。换句话说,你很可能会遇到这样的情况:

             +-----------------+
             |                 |
             v                 |
 "we\0"     "teach\0" "will\0" |   "you\0"
  ^                    ^       |    ^
  |                    |       |    | 
  |          +---------+       |    |
  |          |                 |    |
  |          |       +---------+    |
  |          |       |              |
  |          |       |        +-----+
  |          |       |        |    
Pointer1|Pointer2|Pointer3|Pointer4
  

如果有人能够让我了解我的方法是否正确   正确

您的方法会调用未定义的行为。您在\0终止str[0]后尝试访问内存,因为len大于str[0]的长度。您还与"\0"而不是'\0'进行比较,这没有意义,因为字符串文字"\0"尚未在内存中另一个未指定的位置。

您的方法还有其他一些细节错误,但由于它是基于错误的前提,因此您无法保存它。

  

或其他一些解决方案。

如果问题确实是“我们如何返回最后一个字符串的索引或最后一个字符串的基地址?”,那么只需要记住数组的大小并执行{{1 }}。如果您实际使用的是C ++,请使用size - 1std::array

答案 1 :(得分:2)

  

char * str [] = {&#34; we&#34;,&#34; will&#34;,&#34; teach&#34;,&#34; you&#34;};

这意味着str是一个char类型的指针数组。

所以,str [0]指向我们,str [1]指向will等等。

str不指向一个连续的字符串。

所以,str [3]将指向最后一个字符串&#34;你&#34;。

答案 2 :(得分:1)

  

知道这个字符数组存储在连续的内存位置

你真的不能这样做。请考虑此代码,该代码显示字符串的内存布局。

#include <stdio.h>

char * spoiler = "you";

char * str[] = {"we", "will", "teach", "you"};

int main (void)
{
    int i;
    for (i = 0; i < 4; ++i)
    {
        printf ("%p, %i, %s\n", str[i], str[i] - str[0], str[i]);
    }

    return 0;
}

输出:

10b80, 0, we
10b88, 8, will
10b90, 16, teach
10b78, -8, you

字符串不是连续的,它们被放在8字节的内存边界上。他们甚至没有按照正确的顺序。

计算机对内存中字符串的相对位置没有任何承诺,甚至可以让不同的字符串使用重叠内存。

答案 3 :(得分:1)

我没有看到任何直接回答“如何返回最后一个字符串的索引”的问题,所以...

根据您的示例,您只需使用:

int strCount = sizeof(str) / sizeof(char*);
char* lastString = str[strCount-1];

你不能把每个字符串都放到最后,因为它们可能不是连续的。您必须使用sizeof直接找到数组的最后一个索引。以前字符串的内容或位置无济于事。

sizeof(str)返回32的原因是因为您可能正在编译一个64位应用程序,它使每个char *占用8个字节。四个字符串* 8个字节= 32个字节。

答案 4 :(得分:-1)

该死的,很长一段时间用C / C ++编程。

--- 请注意以下代码有&#39;警告&#39;今天的标准特别致命的2个 -

我无法修复它们,因为我对这些概念有点生疏。我将不得不通过它们。无论如何,如果你已经玩了一段时间的C / C ++,你应该能够修复它们。

#include<stdio.h>
#include<string.h>


int main()
{
   char *str[]={"we", "will", "teach", "you"};
   char **ptr;
   int i,baseAddr,index;
   ptr=&str;

   baseAddr=(*ptr+0);
   for(i=0;i<4;i++)
   {
     //printf("%u\n",str[i]);
      baseAddr=baseAddr+strlen(str[i])+1;
      if(i==3)
      {
        index=i;
      }
   }

   printf("Last Element Address:%d",baseAddr-strlen(str[index])-1);


   return 0;
}

//C++?
#include<iostream>
#include<cstring>
using namespace std;


int main()
{
  char *str[]={"we", "will", "teach", "you"};
  char **ptr;
  int i,baseAddr,index;
  ptr=str;

  baseAddr=(int)(*ptr+0);
  for(i=0;i<4;i++)
  {
    cout<<&str[i]<<endl;
    baseAddr=baseAddr+strlen(str[i])+1;
    if(i==3)
    {
     index=i;
    }
  }

  cout<<"Last Element Address:"<<(ptr+index);

  return 0;
}