相关疑难解决方法(0)

null终止字符串的基本原理是什么?

尽管我喜欢C和C++,但我还是忍不住在选择空终止字符串时不知所措:

  • 在C之前存在长度前缀(即Pascal)字符串
  • 通过允许恒定时间长度查找,长度前缀字符串使得几种算法更快.
  • 长度前缀字符串使得更容易导致缓冲区溢出错误.
  • 即使在32位机器上,如果允许字符串为可用内存的大小,则长度前缀字符串仅比空终止字符串宽三个字节.在16位机器上,这是一个字节.在64位机器上,4GB是一个合理的字符串长度限制,但即使你想将它扩展到机器字的大小,64位机器通常有足够的内存使额外的七个字节排序为null参数.我知道最初的C标准是针对极其糟糕的机器(就内存而言)而写的,但效率论证并没有把我卖给我.
  • 几乎所有其他语言(即Perl,Pascal,Python,Java,C#等)都使用长度前缀字符串.这些语言通常在字符串操作基准测试中胜过C,因为它们对字符串更有效.
  • C++对std::basic_string模板进行了一些纠正,但是期望空终止字符串的普通字符数组仍然很普遍.这也是不完美的,因为它需要堆分配.
  • 空终止字符串必须保留一个字符(即null),该字符不能存在于字符串中,而长度前缀字符串可以包含嵌入的空值.

这些事情中的一些最近比C更明显,因此C对于不了解它们是有意义的.然而,在C出现之前,有几个很平常.为什么选择空终止字符串而不是明显优越的长度前缀?

编辑:由于一些人在我的效率点上询问事实(并且不喜欢我已提供的事实),他们源于以下几点:

  • 使用空终止字符串的Concat需要O(n + m)时间复杂度.长度前缀通常只需要O(m).
  • 使用空终止字符串的长度需要O(n)时间复杂度.长度前缀为O(1).
  • length和concat是迄今为止最常见的字符串操作.在某些情况下,空终止字符串可以更有效,但这些情况发生得更少.

从下面的答案中,这些是空终止字符串更有效的一些情况:

  • 当你需要切断字符串的开头并需要将它传递给某个方法时.即使您被允许销毁原始字符串,也无法在长度前缀的常量时间内执行此操作,因为长度前缀可能需要遵循对齐规则.
  • 在某些情况下,您只需按字符循环字符串,就可以保存CPU寄存器.请注意,这仅适用于您尚未动态分配字符串的情况(因为您必须释放它,因此必须使用您保存的CPU寄存器来保存您最初从malloc和朋友那里获得的指针).

以上都不像长度和连续那样常见.

在下面的答案中还有一个断言:

  • 你需要切断字符串的结尾

但这个不正确 - 它与null终止和长度前缀字符串的时间相同.(Null终止字符串只是在你希望新结束的地方粘贴一个空值,长度前缀只是从前缀中减去.)

c c++ string null-terminated

272
推荐指数
12
解决办法
2万
查看次数

字符数组后的奇怪字符

我是C的真正初学者,但我正在学习!

我之前偶然发现了这个问题,并决定询问原因是什么.请解释一下你的答案,这样我才能学习.

我制作了一个程序,允许你输入5个字符然后显示你写的字符并还原它们,例如:"asdfg" - "gfdsa".奇怪的是,在输入的原始字符之后显示了一个奇怪的字符.

这是代码:

char str[5];
char outcome[] = "OOOOO";
int i;
int u;

printf("Enter five characters\n");

scanf("%s", str);

for(i = 4, u = 0; i >=0; u++, i--){
    outcome[i] = str[u];
}

printf("\nYou wrote: %s. The outcome is: %s.", str , outcome);


return 0;
Run Code Online (Sandbox Code Playgroud)

如果我输入:"asdfg"它显示:"asdfg♣",为什么?

谢谢你的时间,请解释你的答案:)

c arrays string scanf character

7
推荐指数
2
解决办法
3万
查看次数

为什么在String数组中添加Null字符?

我知道我们必须使用空字符来终止字符串数组,如下所示:

char str[5] = { 'A','N','S','\0' };
Run Code Online (Sandbox Code Playgroud)

但我只是想知道为什么使用空字符来终止这样的数组是必要的?

另外,为什么我们不添加null charater来终止这些: -

char str1[5]="ANS";
Run Code Online (Sandbox Code Playgroud)

c arrays string character-arrays

6
推荐指数
1
解决办法
2万
查看次数

使用strncpy时堆栈和堆的奇怪行为

我发现了一个非常有趣的问题.

当我使用以下代码时:

int main() {
    char * in = "hi, ";
    char str[10];
    strncpy(str, in, 2);
    printf("output = %s", str);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我的结果是什么,printf没有用.

但如果我用这个:

int main() {
    char * in = "hi, ";
    char * str = malloc(sizeof(char) * 10) ;
    strncpy(str, in, 2);
    printf("output = %s", str);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我能得到我的期望.

为什么会这样?是因为堆栈和堆?究竟是如何产生这种巨大差异的呢?

c string heap stack

4
推荐指数
2
解决办法
284
查看次数

为什么这个printf()语句不能在C中打印两个字符串变量?

我在学习C的过程中一直在疯狂地研究.我一直在调试一个C程序,我认为这里有一些重大问题.现在我有关键问题.我制作了一个虚拟程序,在一个语句中打印两个字符串,如下所示:

   #include<stdio.h>

int main(int argc, char* argv[])
{
    char *herp = "Derp";
    char *derp = "Herp";

    printf("Herp %s Derp %s\n", herp, derp);

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

这按预期打印出来.我明白了

Herp Derp Derp Herp
Run Code Online (Sandbox Code Playgroud)

所以,我想,让我通过做类似的事情调试我自己的程序.我的程序中的以下行

printf("word is: %s and jumbled word is: %s\n", word, jumbleWord);
Run Code Online (Sandbox Code Playgroud)

应打印出类似的东西

Word is: word and jumbled word is: dowr
Run Code Online (Sandbox Code Playgroud)

但它打印出类似的东西

and jumbled word is: dowr
Run Code Online (Sandbox Code Playgroud)

输出的第一部分在哪里?我需要能够在同一行上打印这两个进行调试.此外,这样的陈述不起作用这一事实告诉我,真的很奇怪的事情正在发生,我秃头撕裂了我的头发.正如我的链接帖子所示,我最终想比较这些字符串值,但是如果printf()不能正常工作,我怎么能这样做呢?

我发布了下面的整个程序,这样你就可以看到一切都在发生.我只是在学习如何使用指针.当我想混淆一个单词并且效果不好时,我最初有两个指针指向相同的内存!所以我修复了它,并用我需要的单词获得了两个独立的内存空间.现在,我只是无法打印它们.鉴于以下代码,这一切都有意义:

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

#define MAX_WORD_LENGTH 25

//Define global variables 
int numWords; 

//Preprocessed Functions 
void jumblegame();
void readFile(char *[]);
void …
Run Code Online (Sandbox Code Playgroud)

c string debugging printf

4
推荐指数
1
解决办法
3万
查看次数

C中的char指针初始化

关于字符指针以及它们是如何工作的我不太清楚.

程序构建,但在运行时崩溃.

 char *ab = NULL;
 //ab = "abc123"; // works fine
 sprintf(ab, "abc%d", 123); // this line seems to crash the program
Run Code Online (Sandbox Code Playgroud)

当sprintf接受(char*str)作为第一个参数时,我不明白这是怎么回事.

有人可以向我解释一下吗?

c string pointers char

3
推荐指数
1
解决办法
3万
查看次数

使用'\ 0'作为比较操作数

我的函数应列出屏幕上char数组的所有元素.但是如果阵列完成它应该停止.数组的大小是可变的.我以为数组以'\ 0'结尾.所以我这样做了:

for(int i=0; i< size; i++){
    if(word[i] != '\0')
        cout<< word[i];
}
Run Code Online (Sandbox Code Playgroud)

但该计划并不止于此.它会创建一些随机符号.

例如char number [] ="0123"
该程序给出:0123§&

我的if条件出了什么问题?

c++ arrays

1
推荐指数
1
解决办法
70
查看次数