(数组和字符串)Java 与 C 的区别

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3802470/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-14 05:12:38  来源:igfitidea点击:

(array & string) Difference in Java vs. C

javac

提问by Subhransu Mishra

I know about C and I am entering into Java and confused about its approach towards arrays and strings. It's totally different from arrays and strings in C. Please help me understand what is actually the difference between C and Java (for strings and arrays).

我了解 C 并且我正在进入 Java 并且对其处理数组和字符串的方法感到困惑。它与 C 中的数组和字符串完全不同。请帮助我理解 C 和 Java 之间的实际区别(对于字符串和数组)。

采纳答案by Grodriguez

In C, a string is typically just an array of (or a pointer to) chars, terminated with a NUL (\0) character. You can process a string as you would process any array.

在 C 中,字符串通常只是一个(或指向)字符的数组,以 NUL (\0) 字符结尾。您可以像处理任何数组一样处理字符串。

In Java, however, strings are not arrays. Java strings are instances (objects) of the java.lang.Stringclass. They represent character data, but the internal implementation is not exposed to the programmer. You cannot treat them as arrays, although, if required, you can extract string data as an array of bytes or chars (methods getBytesand getChars). Note also that Java chars are 16-bits, always, while chars in C are typically (not always) 8-bit.

然而,在 Java 中,字符串不是数组。Java 字符串是类的实例(对象)java.lang.String。它们代表字符数据,但内部实现不暴露给程序员。您不能将它们视为数组,但如果需要,您可以将字符串数据提取为字节或字符数组(方法getBytesgetChars)。另请注意,Java 字符始终为 16 位,而 C 中的字符通常(并非总是)8 位。

回答by sushil bharwani

String is a object in JAVA its unlike a Character array in C

String 是 JAVA 中的一个对象,它不同于 C 中的 Character 数组

回答by Prof. Falken contract breached

A string in C is just an array of chars. There is nothing but the convention that when a NUL character (\0) is found, the string ends.

C 中的字符串只是一个字符数组。只有当找到 NUL 字符 (\0) 时,字符串结束的约定。

All string support depends on functions in the C standard library, such as strlen(), strcpy() and so on.

所有字符串支持都依赖于 C 标准库中的函数,例如 strlen()、strcpy() 等。

To tell the size of a C "string", you have to pass a pointer to a separate function. You could argue that there are no strings in C at all, just conventions for arrays of char.

要告诉 C “字符串”的大小,您必须传递一个指向单独函数的指针。您可能会争辩说 C 中根本没有字符串,只有字符数组的约定。

Java, on the other hand, has strings built in as a part of the language itself. The Java String has methods, which can tell you its size for instance. Java has primitive types, like C: float and int.

另一方面,Java 将字符串作为语言本身的一部分内置。Java String 有方法,例如可以告诉您它的大小。Java 有原始类型,如 C: float 和 int。

But it also has "Objects" and String is a kind of object.

但它也有“对象”,而字符串是一种对象。

This is so far very much like the difference between C and C++ too.

到目前为止,这也非常类似于 C 和 C++ 之间的区别。

回答by John Bode

Arrays:

数组:

The first obvious difference is that Java doesn't use the same declaration syntax for arrays as C. In C, the array subscript is part of the declarator, whereas in Java it's part of the type specification:

第一个明显的区别是 Java 不使用与 C 相同的数组声明语法。在 C 中,数组下标是声明符的一部分,而在 Java 中它是类型规范的一部分:

int[] arr;  // Java, arr is null until array object is instantiated
int arr[];  // C, incomplete declaration

Note that, in Java, arrexists but is null-valued. In C, arrdoesn't exist until a complete declaration appears.

请注意,在 Java 中,arr存在但为空值。在 C 中,arr在出现完整声明之前不存在。

int[][] 2Darr; // Java, arr is null until array object is instantiated
int 2Darr[][]; // Illegal declaration in C; size must be specified for at least
               // the outer dimension

Array objects in Java must be instantiated with a newoperation, and it's there that the array size is specified:

Java 中的数组对象必须使用new操作实例化,并且在那里指定数组大小:

int[] arr = new int [10];
int[][] 2Darr = new int[10][20];

If the array is not of a primitive type, each individual array element must be separately instantiated:

如果数组不是原始类型,则必须单独实例化每个单独的数组元素:

String[] strs = new String[10];
for (int i = 0; i < strs.length; i++)
  strs[i] = new String("some value");

Array expressions in Java do not have their types "decay" to pointer types like array expressions in C (which is handy, since Java doesn't have pointer types per se); array types in Java are "first class" objects, meaning they retain all their type characteristics in any context. When you pass an array object to a method, the method receives an array object, not a pointer.

在Java数组表达式不必它们的类型“衰变”到指针类型,如在C(这是很方便的,因为Java没有指针类型数组表达式本身); Java 中的数组类型是“第一类”对象,这意味着它们在任何上下文中都保留其所有类型特征。当您将数组对象传递给方法时,该方法接收的是数组对象,而不是指针。

Java arrays know how big they are (given by the .lengthattribute).

Java 数组知道它们有多大(由.length属性给出)。

Strings:

字符串:

Unlike C, Java supplies a distinct String data type. Do not think of Java strings as 0-terminated arrays of char; they are something different.

与 C 不同,Java 提供了一种独特的 String 数据类型。不要将 Java 字符串视为以 0 结尾的字符数组;它们是不同的东西。

Java String objects are immutable; you cannot modify the contents of a String object. You can create a new String object from the modified contents of an existing String object. There are also classes like StringBuilder and StringBuffer that allow you to manipulate character data directly and create new String objects.

Java String 对象是不可变的;您不能修改 String 对象的内容。您可以从现有 String 对象的修改内容创建一个新的 String 对象。还有像 StringBuilder 和 StringBuffer 这样的类,它们允许您直接操作字符数据并创建新的 String 对象。

Hope that helps.

希望有帮助。

回答by Manoj R

In C string is indeed array of character ended by '\0'. In Java string is a class. The java string can better be compared with std::string in C++ rather than C character array.

在 C 字符串中确实是以 '\0' 结尾的字符数组。在 Java 中,字符串是一个类。java 字符串可以更好地与 C++ 中的 std::string 进行比较,而不是与 C 字符数组进行比较。

Declaration :- In C - char str[100]; In Java - String str;

声明 :- 在 C 中 - char str[100]; 在 Java 中 - 字符串 str;

In Java in most of the cases you don't need to worry about the string implementation as rich varieties of member functions are provided to work with it. In C also there are many APIs like strlen, strcpy, strcat, which are quite sufficient for normal operations.

在大多数情况下,在 Java 中您不需要担心字符串实现,因为提供了丰富的成员函数来使用它。在 C 中也有很多 API,如 strlen、strcpy、strcat,对于正常操作来说已经足够了。

The main difference comes in when you have to do some operations involving two strings. e.g. lets say assigning one string to other. In jave it's straight forward.

当您必须执行一些涉及两个字符串的操作时,主要区别在于。例如,让我们说将一个字符串分配给另一个。在 java 中,它是直截了当的。

String str1("This is Stack Overflow.");
String str2;

String str1("这是堆栈溢出。");
字符串 str2;

str2 = str1;

str2 = str1;

But In C you will have to use a loop to assign each character. Now again that does not mean that Java does it faster, because internally java also does the same thing. Just that the programmer is unaware of that.

但是在 C 中,您必须使用循环来分配每个字符。再说一次,这并不意味着 Java 做得更快,因为在内部 java 也做同样的事情。只是程序员不知道这一点。

In Java some operations can be done using natural operators e.g. comparison.

在 Java 中,一些操作可以使用自然运算符来完成,例如比较。

str1 == str2.

str1 == str2。

But in C you will have to use strcmp function for this.

但是在 C 中,您必须为此使用 strcmp 函数。

strcmp(str1,str2);

strcmp(str1,str2);

In short while working in C you must and must know how to operate on string internally. In Java you must not.

简而言之,在使用 C 语言时,您必须并且必须知道如何在内部对字符串进行操作。在 Java 中你不能。

Now in C you will also have to be extra careful when you are creating string on heap area.

现在在 C 中,在堆区域创建字符串时也必须格外小心。

char * str1 = malloc(100);

char * str1 = malloc(100);

You will have to free this memory using free(str1). In Java the programmer need not aware of heap memory or stack memory so such thing do not come into picture.

您必须使用 free(str1) 释放此内存。在 Java 中,程序员不需要知道堆内存或堆栈内存,因此不会出现这种情况。

回答by Aboelnour

If you really need to know the difference you need to know the diff between ptr in C and ref in java
when you say in C: char str[10]; ==> you allocate a sequence 10 blocks in memory and every block's size is sizeof(char) and terminated by null so you can deal with strings with normal ptr operations.

如果你真的需要知道区别,你需要知道 C 中的 ptr 和 java 中的 ref 之间的区别,
当你在 C 中说: char str[10]; ==> 您在内存中分配了一个 10 个块的序列,每个块的大小都是 sizeof(char) 并以 null 结尾,因此您可以使用正常的 ptr 操作处理字符串。

java: when you say String str; ==> you create an object java.lang.String which inherit some methods which in the java.lang.String Class like compare(),equals(),contains(),charAt() and more.

java:当你说String str; ==> 你创建了一个对象 java.lang.String ,它继承了 java.lang.String 类中的一些方法,比如 compare()、equals()、contains()、charAt() 等等。

C: to perform normal String manipulation you treat with ptrs or you using prepared function from header files which inside it deals with block of memory no more no less.
Ex: comparing 2 strings => strcmp(str1,str2);

C:要执行正常的字符串操作,您使用 ptr 进行处理,或者使用头文件中的准备好的函数,其中处理的内存块不多不少。
例如:比较 2 个字符串 => strcmp(str1,str2);

java:as I said every thing in java is an object if you want to compare 2 string:
String str1;
String str2;
str1.equals(str2);

java:正如我所说,如果你想比较 2 个字符串,java 中的每件事都是一个对象:
String str1;
字符串 str2;
str1.equals(str2);

C: a String is must be NULL-Terminated to know when you should stop and if you try to read the block after the string no thing bad would happen (it will compile and wouldn't crash probably)

C: 字符串必须以 NULL 结尾才能知道何时应该停止,如果您尝试在字符串之后读取块,则不会发生任何不好的事情(它会编译并且可能不会崩溃)

Java: as I said String is an object so you don't need to deal with memory if you try to access an element outside the String it will throw an indexOutOfBoundException and your program would crash unless you handle this Exception.

Java:正如我所说的 String 是一个对象,因此如果您尝试访问 String 外部的元素,则不需要处理内存,它将抛出 indexOutOfBoundException 并且除非您处理此异常,否则您的程序将崩溃。

回答by haylem

In C

在 C

Arrays

数组

Arrays in C are simply syntactic sugar to access contiguous memory spaces, or - vulgarizing it shamelessly here - a variant of a pointer notation. To avoid allocating big chunks of contiguous memory and avoid having to reallocate your memory yourself manipulating data of variable size, you then resort to implementations of common Computer Science Data Structure concepts (for instance, a linked list, which uses a pointer to indicate the memory address of the next element in a series).

C 中的数组只是访问连续内存空间的语法糖,或者 - 在这里无耻地粗俗化 - 指针符号的变体。为了避免分配大块的连续内存并避免自己重新分配内存以操作可变大小的数据,然后您求助于常见的计算机科学数据结构概念的实现(例如,链表,它使用指针来指示内存系列中下一个元素的地址)。

You can substitute pointer arithmetic with array notations in C, and vice versa.

您可以用 C 中的数组符号代替指针算术,反之亦然。

The following will print the 5 elements of an array using different access methods:

以下将使用不同的访问方法打印数组的 5 个元素:

#include <stdio.h>

int main(int ac, char **av) {
  char arr[2] = {'a', 'b'};

  printf("0:%c 0:%c 1:%c 1:%c\n", arr[0], *arr, arr[1], *(arr + 1));
  return (0);
}

The following will be valid with int variables. Notice the slight modification to accomodate for the size of an integer:

以下对 int 变量有效。请注意为适应整数大小的轻微修改:

#include <stdio.h>

int main(int ac, char **av) {
  int arr[2] = {42, -42};

  printf("0:%d 0:%d 1:%d 1:%d\n", arr[0], *arr, arr[1], *(arr + 4));
  return (0);
}

(To obtain the size of a given data type, resort to the use of sizeof.)

(要获得给定数据类型的大小,请使用sizeof。)

Strings

字符串

Here I assume you want to know about the conventional C-string implementation, and not one provided by a 3rd-party library.

在这里,我假设您想了解传统的 C 字符串实现,而不是第 3 方库提供的实现。

Strings in C are basically simply arrays of characters. The main reason for this is obvious: as you need to often manipulate strings and print them to a stream, using a contiguous memory space makes sense and is an easy implementation. However, as you need to remember the size of your contiguous memory space to not inadvertently access something forbidden, we rely on the concept of a "NULL-terminated string", meaning a string of N characters is a actually an array of N + 1 characters terminated by a trailing '\0' character, which is used as the de-facto character to look for when you want to reach the end of a string.

C 中的字符串基本上只是字符数组。这样做的主要原因很明显:因为您需要经常操作字符串并将它们打印到流中,所以使用连续的内存空间是有意义的并且是一个简单的实现。但是,由于您需要记住连续内存空间的大小以免无意中访问被禁止的内容,因此我们依赖于“以 NULL 结尾的字符串”的概念,这意味着 N 个字符的字符串实际上是一个 N + 1 的数组以尾随 '\0' 字符结尾的字符,当您想要到达字符串的末尾时,该字符用作查找的事实上的字符。

A straightforward declaration would be:

一个简单的声明是:

char *test = "my test";

which would be equivalent to:

这相当于:

char test[8] = { 'm', 'y', ' ', 't', 'e', 's', 't', '
test[4] = 'H'; /* expect a violent complaint here */
' };

(Notice the trailing '\0')

(注意尾随的 '\0')

However, you have to realize that in that case, the string "my test" is static, and that's the memory space you are directly pointing to. Which means you will encounter issues when trying to dynamically modify it.

但是,您必须意识到,在这种情况下,字符串“my test”是静态的,这就是您直接指向的内存空间。这意味着您在尝试动态修改它时会遇到问题。

For instance, this would blow up in your face (following thee previous declaration):

例如,这会在你的脸上爆炸(按照你之前的声明):

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

int main(int ac, char **av) {
  char *test = strdup("my test");

  printf("%s\n", test);
  return (0);
}

So to have a string you can actually modify you can declare a string simply as:

因此,要拥有一个您可以实际修改的字符串,您可以简单地将字符串声明为:

String myNewStr = someString + "another string";

Where strdup()is a function of the C standard library allocating memory for your string and injecting the characters in there. Or you can allocate memory yourself with malloc()and copy characters manually or with a function like strcpy().

其中strdup()是 C 标准库的一个函数,它为您的字符串分配内存并在其中注入字符。或者您可以使用malloc()自己分配内存并手动复制字符或使用strcpy() 之类的函数。

This particular declaration is thus mutable, and your are free to modify the content of the string (which in the end is just a dynamically allocated array of characters, allocated with malloc()).

因此,此特定声明是可变的,您可以自由修改字符串的内容(最终它只是一个动态分配的字符数组,使用malloc()分配)。

If you need to change the length of this string (add/remove characters to/from it), you will need to everytime be wary of the allocated memory. For instance, calling strcat()will fail if you haven't reallocated some additional memory first. Some functions, however, will take care of this for you.

如果您需要更改此字符串的长度(向其中添加/从中删除字符),则每次都需要注意分配的内存。例如,如果您没有先重新分配一些额外的内存,则调用strcat()将失败。但是,某些功能会为您解决这个问题。

The C string does NOTsupport Unicodeby default. You need to implement to manage code points yourself, or consider using 3rd-party library.

默认情况下,C 字符串支持Unicode。你需要自己实现来管理代码点,或者考虑使用3rd-party library。



In Java

在 Java 中

Arrays

数组

Arrays in Java are very close to their C parent (to the point that we even have a method for efficient array-to-array-copy support using a bare-bone native implementation: System.arraycopy()). They represent contiguous memory spaces.

Java 中的数组非常接近它们的 C 父对象(以至于我们甚至有一种使用裸骨本机实现的高效数组到数组复制支持的方法: System.arraycopy())。它们代表连续的内存空间。

However, they wrap these bare-bone arrays within an object (which keeps track of the size/length of the array for you).

但是,它们将这些基本数组包装在一个对象中(它会为您跟踪数组的大小/长度)。

Java arrays can have their content modified, but like their C counterpart, you will need to allocate more memory when trying to expand them (except you do it indirectly, and will usually reallocate a complete array instead of doing a realloc()like in C).

Java 数组可以修改它们的内容,但就像它们的 C 对应物一样,在尝试扩展它们时需要分配更多内存(除非您是间接进行的,并且通常会重新分配一个完整的数组,而不是像在 C 中那样执行realloc())。

Strings

字符串

Strings in Java are immutable, meaning they cannot be changed, once initialized, and operations on String actually create new String instances. Look up StringBuilderand StringBufferfor efficient string manipulation with an existing instance, and beware of their internal implementation details (especially when it comes to pre-setting the capacity of your buffer efficiently, to avoid frequent re-allocations).

Java 中的字符串是不可变的,这意味着一旦初始化它们就无法更改,并且对 String 的操作实际上会创建新的 String 实例。查找StringBuilderStringBuffer以使用现有实例进行有效的字符串操作,并注意它们的内部实现细节(尤其是在有效地预先设置缓冲区容量以避免频繁重新分配时)。

for instance, the following code uses produces a 3rd String instance out of someStringand "another string":

例如,以下代码使用someString和“另一个字符串”生成第三个字符串实例:

##代码##

In the underlying implementation, the Java String* classes also use an arrays of characters, like their C parent.

在底层实现中,Java String* 类也使用字符数组,就像它们的 C 父类一样。

This implies that they use more memory than the bare-bone C implementation, as you have the overhead of your instance.

这意味着它们比简单的 C 实现使用更多的内存,因为您有实例的开销。

Not only that, they actually use a lot more memory because the Java String class provides Unicodesupport by default, meaning it allows for multiple code pointsper character (which is not a trivial thing to do in C, in comparison).

不仅如此,它们实际上使用了更多的内存,因为 Java String 类默认提供Unicode支持,这意味着它允许每个字符有多个代码点(相比之下,这在 C 中并不是一件容易的事)。

On the other, notice that except if considering performance, you don't need to worry about threading, memory, and implementing functions looking for trailing '\0' characters.

另一方面,请注意,除非考虑性能,否则您无需担心线程、内存和实现寻找尾随 '\0' 字符的函数。



What More?

还有什么?

A lot more could be said and researched. Your question is fairly broad at the moment, but I'll be glad to edit if you add sub-questions in your comments.

可以说和研究的还有很多。您的问题目前相当广泛,但如果您在评论中添加子问题,我会很乐意进行编辑。

Also, maybe this could help:

另外,也许这可以帮助: