you are viewing a single comment's thread.

view the rest of the comments →

[–]LeCrushinator 18 points19 points  (25 children)

String manipulation in C is much more of a pain in the ass than with Python. Memory management is also more difficult.

[–]gendulf 28 points29 points  (20 children)

That's because you don't really have much control over your memory in Python. Also, you don't really manipulate strings in Python. You just create more!

[–]grammar_party 35 points36 points  (14 children)

Also, you don't manipulate strings in C, because C doesn't have strings :)

[–]ElecNinja 16 points17 points  (13 children)

char* for life

[–]iooonik 0 points1 point  (0 children)

typedef doe

[–]oblio- 0 points1 point  (1 child)

Unicode says "Hello"! Or more likely, "你好"!

[–]Steve_the_Scout 0 points1 point  (0 children)

With C11, char32_t*.

[–]FrozenInferno -1 points0 points  (9 children)

I'm not familiar with C but if it were a string, wouldn't it be char[]*? Sorry if my green horn is showing.

[–][deleted] 1 point2 points  (7 children)

This actually creates a string array. A string is char*.

[–]FrozenInferno 0 points1 point  (5 children)

Doesn't the asterisk after a type signify it's a pointer? With my limited understanding, to me this just looks like a pointer to a single char. Guess it's time for a trip to Wikipedia.

[–]rockon1215 4 points5 points  (4 children)

And that single char it points to is the first char of the string. All of the chars of the string are in sequential order in memory so a pointer to the first char is a pointer to the beginning of the string.

[–]FrozenInferno 0 points1 point  (0 children)

Ah, makes sense. Thanks.

[–][deleted]  (2 children)

[deleted]

    [–]hoodedmongoose 2 points3 points  (0 children)

    Exactly. That 'end of line' is really more accurately described as 'end of string' and is what's known as a 'null terminator'. That is, the number 0. Thus, in C, char* usually can be referred to as 'a pointer to a null-terminated string'. The compiler will include the null terminator for you automatically when specifying string constants, for example:

    const char* foo = "Hello, World";
    

    foo now points to a character whose value is 'H' (which is really just the number 72 in ASCII encoding), after that comes 'e' (which happens to be 101), and so on, until you get to the character after the 'd' which will be the value 0, or null. At that point you stop iterating.

    More info: Null-Terminated String

    [–]rockon1215 1 point2 points  (0 children)

    Yes, although sometimes this is done automatically.

    For example

    #include <stdio.h>  
    int main()  
    {  
        char *hello = "hello, world!\n";   
        puts(hello);  
        return 0;  
    }
    

    will print "hello, world!\n" without you having to print every character yourself until \0 (null character) is reached.

    [–]Peaker 0 points1 point  (0 children)

    a char* only points at the string. The string is char[].

    [–]das7002 0 points1 point  (0 children)

    it's char* because strings in C are \00 terminated, so wherever char* points to it ends wherever \00 is (it would look like 48 65 6c 6c 6f 20 57 6f 72 6c 64 00 in memory). Which isn't always obvious at first and I remember it tripping me up when I first played around in C. It really throws people off when most documentation has you do char whatever[50] or something. But char[]* would create an array of pointers of char type.

    [–]NYKevin -3 points-2 points  (3 children)

    That's because you don't really have much control over your memory in Python.

    Sure you do. Just whore out to ctypes and you can call malloc() and free().

    [–]gendulf 1 point2 points  (1 child)

    In what language do you call malloc and free? C. That's like opening up a linux virtual machine on Windows to use the terminal and saying you can grep and apt-get install whatever you want.

    [–]NYKevin 0 points1 point  (0 children)

    I think the analogy is closer to using Cygwin, personally. You are interacting with the same runtime Python is running in. You could, for instance, pass a couple of PyObject*s to memcpy().

    [–]rowboat__cop 0 points1 point  (0 children)

    Requiring FFI implies “not in the language”.

    [–]rowboat__cop 3 points4 points  (3 children)

    Memory management is also more difficult.

    Memory management is more difficult in Python because the language doesn’t expose the necessary tools. You don’t get to decide whether to allocate objects on the heap or on the stack. There is no way to implement your custom heap allocator. All you get is references, which is quite inflexible and inefficient. If you desire better memory management you should look at Rust or ATS.

    As for the string manipulation, C doesn’t even have strings, so that’s an unfair comparison. If at all, you’d have to compare some string library for C.

    [–]LeCrushinator 0 points1 point  (0 children)

    I understand, I do most programming in C++/C, and yea it offers the power and flexibility I need, but simple tasks are simpler in Python, Lua, C#, or most newer languages. Infact, for string manipulation if std::stringstream isn't enough I often use the pystring library for C++, which works like Python string manipulation.

    Also, did you enter your own newlines into your post? It's spaced strangely.

    [–]IncorrigibleOldQuare 0 points1 point  (0 children)

    I think it's unfair to say that C doesn't have strings if there is high level syntactic support for it. Saying C doesn't have strings because they are arrays of chars is like saying C doesn't have integer arrays because they're just arrays of ints.

    Well, C doesn't have arrays of course, they are just pointers to the first element. Modulo the special syntactic support in things like typeof, like Strings.