简体   繁体   English

puts函数,指针和字符串如何工作? 为什么strchr()在搜索到的字符之后会得到字符?

[英]how puts function , pointer and string work? why would strchr() get characters after the searched character?

The example is below. 示例如下。 In my understanding, t and p are the same pointers pointing to the address of a string? 以我的理解, tp是指向字符串地址的相同指针吗? I get confused with pointer and string. 我对指针和字符串感到困惑。 Would puts(p) give the address of the string instead of characters? puts(p)给出字符串的地址而不是字符吗? Also, I can't figure out how strchr funcition works. 另外,我不知道strchr如何工作。 ++p would point to the next character after ':', that is how it works, is it correct? ++ p会指向':'之后的下一个字符,这就是它的工作原理,对吗? Please help! 请帮忙! Thanks. 谢谢。

char *t = "MEAS:VOLT:DC?";
char *p;  
p = t;     
puts( p );
while(( p = strchr( p, ':' )) != NULL )
{ puts( ++p )}}

What is a pointer? 什么是指针? A pointer is variable that stores an address (memory location). 指针是存储地址(内存位置)的变量。 This can be the address of another variable 这可以是另一个变量的地址

int n = 9;
int *ptr = &n; // stores the address of n

or it can be the start of a memory block, for example a dynamically allocated memory block: 也可以是内存块的开始,例如动态分配的内存块:

int *fields = malloc(len * sizeof *fields);

Whatever address a pointer is pointing to, we use pointers to directly access the memory that is stored in the pointer (we also say where the pointer is pointing to ). 无论指针指向什么地址,我们都使用指针直接访问指针中存储的内存(我们也说了指针指向的位置 )。

What are strings? 什么是琴弦? What you've got to understand is that C does not have a string type like other programming languages do. 您必须了解的是C没有像其他编程语言那样具有字符串类型。 In C a string is just a sequence of 8-bit values (representing characters) that end with the '\\0' -terminating byte. 在C语言中,字符串只是一个以'\\0'结尾的8位值(表示字符)的序列。 The natural type for a single character is a char , that's why we use char* or char[] to get a string. 单个字符的自然类型是char ,这就是为什么我们使用char*char[]获取字符串的原因。

When you do 当你做

const char *str = "Hello";

str points somewhere in memory and it looks like this: str指向内存中的某个位置,看起来像这样:

b = base address of the first character in the
    sequence

b     b+1   b+2   b+3   b+4   b+5
+-----+-----+-----+-----+-----+------+
| 'H' | 'e' | 'l' | 'l' | 'o' | '\0' |
+-----+-----+-----+-----+-----+------+

The integer values of character constants like 'H' are determine by the ASCII table. 字符常量(如'H'的整数值由ASCII表确定。 So in reality the memory looks like this: 因此,实际上内存看起来像这样:

b = base address of the first character in the
    sequence

b     b+1   b+2   b+3   b+4   b+5
+----+-----+-----+-----+-----+-----+
| 72 | 101 | 108 | 108 | 111 |  0  |
+----+-----+-----+-----+-----+-----+

So str points to that location b , str[0] is the first character, str[1] is the second, etc. As you see, to get a string, all you need is access to the first character in the sequence. 因此, str指向该位置bstr[0]是第一个字符, str[1]是第二个字符, str[1] 。如您所见,要获取字符串,您所需要做的就是访问序列中的第一个字符。 That's the reason why we use a char* pointer to address strings, because with the char* pointer we have access to the first and the subsequent characters in the string. 这就是为什么我们使用char*指针来寻址字符串的原因,因为使用char*指针,我们可以访问字符串中的第一个和后续字符。

A function like puts(str) does the following: puts(str)这样的函数执行以下操作:

  • is the current character the '\\0' -terminating byte? 当前字符是'\\0'终止字节吗?
    • if yes, then exit 如果是,则退出
    • if no, then print the character and advance to the next one 如果不是,则打印字符并前进到下一个字符

So puts(str) does not print the address where the pointer is pointing, it prints the contents of the memory where the pointer is pointing to. 因此puts(str)不会打印指针所指向的地址,而是打印指针所指向的内存的内容。

A function like strchr works like this: strchr这样的函数的工作方式如下:

man strchr 人strchr

 char *strchr(const char *s, int c); 

DESCRIPTION 描述

The strchr() function returns a pointer to the first occurrence of the character c in the string s . strchr()函数返回一个指针,该指针指向字符串s字符c的首次出现。

Now that you know about the memory layout of strings, this should be easy to understand. 现在您已经知道了字符串的内存布局,这应该很容易理解。 Let's take a look at this: 让我们看一下:

const char *str = "Hello";
char *f = strchr(str, 'l');

Remember, the memory layout for where str is pointing to is: 记住, str指向的内存布局是:

b = base address of the first character in the
    sequence

b     b+1   b+2   b+3   b+4   b+5
+-----+-----+-----+-----+-----+------+
| 'H' | 'e' | 'l' | 'l' | 'o' | '\0' |
+-----+-----+-----+-----+-----+------+
               ^
               ¦
       first occurrence
            of 'l'

so what strchr returns is a pointer pointing to b+2 (or str+2 , because in my example b is the value that the pointer str is storing). 因此strchr返回的是指向b+2的指针(或str+2 ,因为在我的示例中b是指针str存储的值)。

That's why when do you puts(str) you get Hello , and when you do puts(f) you get llo . 这就是为什么当您puts(str) llo puts(str)时会显示Hello ,而当您puts(f)则会显示llo

A simple implementation for strchr is: strchr一个简单实现是:

char *strchr(const char *s, int c);
{
    // stop when the \0-terminating byte is reached
    for(size_t i = 0; s[i] != '\0'; ++i)
    {
        if(s[i] == c)
            return &s[i];  // or return s+i; using pointer arithmetic
    }

    return NULL; // c is not found in the string
}

So what does this do? 那么,这是做什么的呢?

while(( p = strchr( p, ':' )) != NULL )
{ 
    puts( ++p )
}

The first time that strchr returns a value that is not NULL , it will return a pointer to the first occurrence of the colon : . strchr第一次返回的值不为NULL ,它将返回一个指向第一次出现的冒号的指针: puts(++p) is equivalent to puts(++p)等效于

p = p + 1; // let p point to the next next character after the colon
puts(p);   // prints the string

then strchr is executed again, because there is one more colon : in the string, it will not return NULL but the location of where : is stored. 然后再次执行strchr ,因为在字符串中还有一个冒号: ,它不会返回NULL而是会存储where :的位置。 The next time the loop is executed, there are no more colons and strchr will return NULL , thus ending the loop. 下次执行循环时,不再有冒号, strchr将返回NULL ,从而结束循环。 So the output will be: 因此输出将是:

MEAS:VOLT:DC?       // puts( p );
VOLT:DC?            // 1. puts( ++p ); of the loop
DC?                 // 2. puts( ++p ); of the loop

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM