在递增指针后使用strlen()会发生什么?

时间:2018-03-24 21:28:13

标签: c arrays pointers strlen gets

我对strlen()进行了一些研究并提出了一个问题。

假设我有一个50元素数组和一个指向第一个元素的指针,意思是:

char A[50],*x;
gets(A);
x=&A[0];

根据我的理解,strlen(x)应该给我字符串的长度。

我的问题是,当我增加x时会发生什么?

4 个答案:

答案 0 :(得分:7)

首先,对于题外话表示抱歉,但请不要使用过时的gets()功能。请改用fgets

在回答您的问题时,如果x是指向有效非空字符串的指针,则strlen(x+1)将始终等于strlen(x) - 1

假设我们有这个字符串,x指向它:

     +---+---+---+---+---+---+
  a: | H | e | l | l | o | \0|
     +---+---+---+---+---+---+
       ^
       |
   +---|---+
x: |   *   |
   +-------+

即,x指向字符串的第一个字符。现在,strlen所做的只是从指向字符开始并计算字符,直到它找到终止'\0'

因此,如果我们增加x,现在它指向'e'(也就是说,它指向字符串" ello"),如下所示:

     +---+---+---+---+---+---+
  a: | H | e | l | l | o | \0|
     +---+---+---+---+---+---+
           ^
           |
          /
         /
        /
       |
   +---|---+
x: |   *   |
   +-------+

因此strlen的长度会减少一个。

脚注:我提醒过一个我不止一次遇到的有趣的错误。当您使用malloc为字符串分配空间时,您始终必须记住为终止'\0'包含空格。不要这样做:

char *p = malloc(strlen(str + 1));

我的同事曾经这样做了一次(不,真的,这是一个同事,而不是我!),并且很难找到追踪,因为很容易看到错误的代码并且看不到它不是

char *p = malloc(strlen(str) + 1);
应该是这样的。

答案 1 :(得分:1)

它将比之前的回报少。在C中,字符串只是指向第一个字符的内存地址的指针,因此如果您的字符串是

"ABCDEF"

如果你增加指针,而不是指向' A'它将指向' B',所以新字符串是

"BCDEF"

strlen("BCDEF")为5,而strlen("ABCDEF")为6。

答案 2 :(得分:0)

它给你一个更小的。 x += i大致相当于伪代码x = substr(x, i)。 (请注意,如果i超过x的长度,则会发生不好的事情。)

答案 3 :(得分:0)

您的代码:

char A[50],*x;
gets(A);
x=&A[0];
  

strlen(x)应该给我字符串的长度

     

当我增加x?时会发生什么strlen(x)现在给我的相同   如前所述的价值或较小的价值,若然,为何会发生?

答案比人们想象的要复杂得多。答案是:取决于它!

通过声明A[50]编译器将在堆栈上分配50个字节,这些字节未初始化为任何值。

让我们说A的内容恰好是

A[50] = { '5', '1', '2', '3', 0 /*.............*/ };

然后考虑两种情况:

a)用户输入:<enter>

b)用户输入:'7'<enter>

数组A的内容将用于不同的

a) { 0, '1', '2', '3', 0 /*.............*/ };

b) { '7', 0, '2', '3', 0 /*.............*/ };

strlen的结果可能让您感到惊讶:

这是测试程序和结果:

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

int main(void)
{
    char  A[50] = { '5', '1', '2', '3', 0 };
    char *x;

    gets(A);
    x=&A[0];

    for (int i=0; i < 5; i++)
        printf("%d: %02X\n", i, A[i]);

    printf("strlen(x)  = %zu\n", strlen(x));  
    printf("strlen(x+1)= %zu\n", strlen(x+1)); 

    return 0;
}

测试:

<enter>                                                                                                                                         
0: 00                                                                                                                                        
1: 31                                                                                                                                        
2: 32                                                                                                                                        
3: 33                                                                                                                                        
4: 00                                                                                                                                        
strlen(x)  = 0                                                                                                                               
strlen(x+1)= 3  

7<enter>                                                                                                                                            
0: 37                                                                                                                                        
1: 00                                                                                                                                        
2: 32                                                                                                                                        
3: 33                                                                                                                                        
4: 00                                                                                                                                        
strlen(x)  = 1                                                                                                                               
strlen(x+1)= 0 

如您所知strlen计算从起始位置到遇到第一个'\0'的字符数。如果起始字节等于'\0'而不是strlen(x) = 0

对于方案 a) strlen(x)strlen(x+1)将为03
对于方案 b) strlen(x)strlen(x+1)将为10

请不要使用getsWhy is the gets function so dangerous that it should not be used?)并注意我以十六进制格式打印ASCII个字符,例如'2' = 0x32