your function signature should be:
const char * myFunction() { return "My String"; }
Edit:
Background:
Years passed from this post, and they never thought that it would be voted, because it is so fundamental to C and C ++. However, a slightly more detailed discussion is needed.
In C (for example, C ++), a string is just an array of bytes ending in a zero byte, so the term "string-zero" is used to represent this particular flavor of the string. There are other types of strings, but in C (and C ++) this taste is essentially understood by the language itself. Other languages (Java, Pascal, etc.) use different methodologies to understand "my line".
If you ever use the Windows API (which is in C ++), you will see fairly regular functional parameters, such as: "LPCSTR lpszName". The 'sz' part represents this concept of "string-zero": an array of bytes with a null (/ zero) terminator.
Clarification:
For this "intro" I use the word "bytes" and "characters" interchangeably, because it is easier to learn in this way. Keep in mind that there are other methods (wide characters and multi-byte character systems - mbcs) that are used to manage international characters. UTF-8 is an example of mbcs. For the intro, I calmly “missed” all this.
Memory:
This means that a string like "my string" actually uses 9 + 1 (= 10!) Bytes. It is important to know when you finally get around dynamically distributing strings. Thus, without this "terminating zero", you have no line. You have an array of characters (also called a buffer) hanging in memory.
Data Durability:
Using a function this way:
const char * myFunction() { return "My String"; } int main() { const char* szSomeString = myFunction();
... usually drop you off with random unhandled exceptions / segments, etc., especially down the road.
In short, although my answer is correct - 9 times out of 10 you will end up with a program that crashes if you use it that way, especially if you think it is “good practice” to do it that way. In short: this is usually not the case.
For example, imagine some time in the future, now we need to somehow change the line. As a rule, the encoder will "take the easy way" and (try) to write this code:
const char * myFunction(const char* name) { char szBuffer[255]; snprintf(szBuffer, sizeof(szBuffer), "Hi %s", name); return szBuffer; }
Thus, your program will fail because the compiler (may / may not) freed the memory used by szBuffer by the time printf() called in main() . (Your compiler should also warn you of such problems in advance).
There are two ways to return strings that will not be barf so easily.
- return buffers (static or dynamically allocated) that live for a while. In C ++, use “helper classes” (for example,
std::string ) to handle data durability (which requires changing the return value of a function) or - pass a buffer to a function that is filled with information.
Note that you cannot use strings without using pointers in C. As I showed, they are synonyms. Even in C ++ with template classes, there are always buffers (i.e. pointers) that are used in the background.
So, to better answer (now a modified question). (there will certainly be various “other answers” that can be provided).
Safe Answers:
for example 1. using statically allocated lines:
const char* calculateMonth(int month) { static char* months[] = {"Jan", "Feb", "Mar" .... }; static char badFood[] = "Unknown"; if (month<1 || month>12) return badFood;
What “static” does here (many programmers do not like this type of “distribution”) is that the rows fall into the program data segment. That is, he constantly stands out.
If you switch to C ++, you will use similar strategies:
class Foo { char _someData[12]; public: const char* someFunction() const {
... but it might be easier to use helper classes like std::string if you are writing code for your own use (and not part of the library for sharing with others). A.
for example 2. using buffers defined by a specific user:
This is all the more "fool-tested" way of passing lines around. The returned data is not subject to manipulation by the caller. That is, for example, 1 can easily be abused by the caller and subject you to application errors. Thus, it is much safer (although it uses more lines of code):
void calculateMonth(int month, char* pszMonth, int buffersize) { const char* months[] = {"Jan", "Feb", "Mar" .... }; // allocated dynamically during the function call. (Can be inefficient with a bad compiler) if (!pszMonth || buffersize<1) return; // bad input. Let junk deal with junk data. if (month<1 || month>12) { *pszMonth = '\0'; // return an 'empty' string // OR: strncpy(pszMonth, "Bad Month", buffersize-1); } else { strncpy(pszMonth, months[month-1], buffersize-1); } pszMonth[buffersize-1] = '\0'; // ensure a valid terminating zero! Many people forget this! } int main() { char month[16]; // 16 bytes allocated here on the stack. calculateMonth(3, month, sizeof(month)); printf("%s", month); // prints "Mar" }
There are many reasons why the second method is better, especially if you are writing a library that others will use (you do not need to block a specific allocation / release scheme, third parties cannot break your code, you do not need to reference a specific memory management library), but , like all code, it depends on what you like best. For this reason, most people choose, for example, 1, until they are burned so many times that they no longer want to write it;)
Denial of responsibility:
I retired a few years ago and now my C is a little rusty. This demo code should fully compile with C (this is normal for any C ++ compiler, though).