问题描述
我想更深入的以下行:
的char *文件名=file.txt的;
这我这样做的时候,我们使用 fopen()函数
;
我的问题是:
-
文件名
应该持有一个字符的地址(适用于酷睿2 36位)。为什么我们要放一个'字符串的呢? -
为什么,因为你可能会被存储能够永远存在的地址,编译器会不会产生一个错误(S)?
The expression char* filename="file.txt";
is a valid expression. Reason is type of a string literals in C is char[N]
that can easily decay into char*
, and char[N]
and char*
are compatible. Hence you can assign string address to a char*
pointer variable like you are doing in this expression.
Please read below three points:
- Its a valid address:
No, in the expression char* filename="file.txt";
, filename
is assigned a valid address. Its conceptually something like (assuming address starts with 21):
filename 21 22 23 24 25 26 27 28 29
+---+ +------------------------------------+
|21 |---> |'f'|'i'|'l'|'e'|'.'|'t'|'x'|'t'|'\0'|
+---+ +------------------------------------+
filename pointing to string, a valid address.
and It don't gives any error or warning: try below code example:
example-1:
#include<stdio.h>
int main(int argc, char **argv){
char* filename = "filename.txt";
printf("%s", filename);
return 0;
}
Compile it:
:~$ gcc y.c -Wall -pedantic
~$ ./a.out
filename.txt
No error and waring, its compiling and executing perfectly.
Regarding you comment to my answer:
Strings in C
are bit complex data-structured then simple value variables like int
, char
, float
.
In case of basic data-types:
But for strings, when you do:
char* filename = "filename.txt";
Then you are actually assigning address of string "filename.txt"
to char* pointer variable filename
.
Whereas if you do:
char filename[] = "filename.txt";
// ^ notice [] in declaration
Then you are assigning string "filename.txt"; to an array of char filename[]
, here filename
type is char[]
.
To learn about more deferences in both declarations read: What does sizeof(&arr) return?
A string literal may give you value or address dependences in what context you use it. for example try: printf(" address: %p, value: %s", "Hello", "Hello");
- Compiler do not validates address but check syntax.
The compiler is not responsible to validate that a address is legal. Compiler transplants code and checks syntax errors(for example uncompilable type mismatch). Suppose if you assign a fake address to a pointer it won't give you a waring (if you correctly type casts address). Consider the below example:
example-2:
#include<stdio.h>
int main(int argc, char **argv){
char* filename = "filename.txt";
char* ptr = (char*)0x020202;
printf("%s %s\n", filename, ptr);
return 0;
}
Compile:
$ gcc y.c -Wall -pedantic
And it will not generates any error or waring. Because syntactically all is fine and valid.
(Whereas ptr
assigned a fake address that may not exists).
- Invalid address causes Undefined behavior at runtime
Well, its fine to compile example-2 code where ptr
is assigned a a fake address, and compiler don't generates any error/warning even with stick checking flags options: -Wall -pedantic
.
But executing this code is wrong. It try to access memory address assigning to ptr
in printf statement, And the program will behave abnormally (at different executing instance). In C
-Language standard its called: Undefined behavior.
When you executes this code OS (but not compiler) detects memory right violation by a process -- An invalid access to valid memory gives: SIGSEGV And access to an invalid address gives: SIGBUS. This may cause process terminate/crash with some segmentation fault and coredump.
To learn and know what can be happen when you access illegal memory read: strcat() implementation works but causes a core dump at the end.
这篇关于为什么我们存储字符串中的字符指针,例如fopen()函数;?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!