为什么我们存储字符串中的字符指针,例如fopen()函数;? [英] why do we store string in a character pointer, e.g in fopen();?
问题描述
我想更深入的以下行:
的char *文件名=file.txt的;
这我这样做的时候,我们使用 fopen()函数
;
我的问题是:
-
文件名
应该持有一个字符的地址(适用于酷睿2 36位)。为什么我们要放一个'字符串的呢? -
为什么,因为你可能会被存储能够永远存在的地址,编译器会不会产生一个错误(S)?
文件名应该持有一个字符的地址(酷睿2 36位),为什么我们都在上面放一个字符串?
块引用>这位前pression
的char *文件名=file.txt的;
是一个有效的前pression。原因是在C字符串的类型是的char [N]
,可以很容易衰变成的char *
和的char [N]
和的char *
是兼容的。因此,你可以字符串地址分配给的char *
像你这样的指针变量正在做这个前pression。
为什么编译器,因为你可能会被存储能够永远存在的地址,也不会产生错误?
块引用>请阅读以下三点:
- 它是一个有效的地址:
没有,在EX pression
的char *文件名=file.txt的;
,文件名
被分配一个有效地址。它的概念是这样(假设地址以21开头):21名22 23 24 25 26 27 28 29
+ - + + + ------------------------------------
| 21 | ---> |'F'|'我'|'L'|'E'|'。'|'T'|'X'|'T'|'\\ 0'|
+ - + + + ------------------------------------文件名指向字符串,一个有效的地址。和它不提供任何错误或警告:请尝试以下code例如:
例1:
#包括LT&;&stdio.h中GT;
INT主(INT ARGC,字符** argv的){
字符*文件名=FILENAME.TXT;
的printf(%S,文件名);
返回0;
}编译:
:〜$ GCC y.c -Wall -pedantic
〜$ ./a.out
FILENAME.TXT没有错误,华林,其编制和执行完美。
关于你我的答案评论:
字符串在
C
是有点复杂的数据结构则简单值的变量,比如INT
,字符
,浮动
。在基本数据类型的情况:
INT I = 5;您正在分配值5,变量i
焦C ='A';您正在分配值'A'为char变量c。
浮动F = 5.5F;您正在分配值5.5F浮动变量f。
块引用>但对于字符串,当你这样做:
的char *文件名=FILENAME.TXT;
然后,你实际上是指定字符串的地址
FILENAME.TXT
为char *指针变量文件名
。而如果你做的:
字符文件名[] =FILENAME.TXT;
// ^通知,声明,[]然后你要分配字符串FILENAME.TXT为CHAR
文件名[]
,这里文件名
类型的char [] 数组code>。
要了解在这两个声明的更多deferences阅读:什么的sizeof(安培; ARR )返回?
字符串文字可能会给你的价值或者你用什么情况下它的地址依赖性。例如尝试:
的printf(地址:%P,值:%S,你好,你好);
- 编译器不验证地址,但检查语法。
的编译器是不负责验证一个地址是合法的。编译器移植code和检查语法错误(例如不可编译的类型不匹配)。如果您分配一个假地址的指针它不会给你一个华林(如果你正确类型转换地址)假设。考虑下面的例子:
例2:
#包括LT&;&stdio.h中GT;
INT主(INT ARGC,字符** argv的){
字符*文件名=FILENAME.TXT;
字符* PTR =(字符*)0x020202;
的printf(%s%S \\ n,文件名,PTR);
返回0;
}编译:
$ GCC y.c -Wall -pedantic
和它不会产生任何错误或华林。因为所有的语法是好的,有效的。结果
(而PTR
分配可能不存在假地址)。
- 无效的地址会导致在运行时不确定的行为
那么,它精编例2 code其中
PTR
分配AA假地址,而编译器不产生任何错误/即使有警示棒检查标志选项:-Wall -pedantic
。但是,在执行此code是错误的。它试图访问的内存地址printf语句分配给
PTR
,程序将异常行为(不同的执行实例)。在C
-language标准其名为:未定义行为一>。在执行此code操作系统(而不是编译器)通过过程检测内存侵权问题 - 有效内存的无效访问,得出:SIGSEGV并获得无效的地址给:SIGBUS。这可能会导致终止进程/崩溃与一些段故障,并核心转储。
要了解和知道,当你访问非法的内存读可以发生什么:<一href=\"http://stackoverflow.com/questions/16750998/strcat-implementation-works-but-causes-a-core-dump-at-the-end?answertab=votes#tab-top\">strcat()执行工作,但会导致核心转储在年底。
I am trying to look deeper in the following line:
char* filename="file.txt";
This I do it when we use
fopen()
;My questions are:
filename
is supposed to hold an address of a character (36 bits in core2Duo). Why we are putting a 'string' in it?Why the compiler would not generate an error(s) since you might be storing an address which can never exist?
解决方案filename is supposed to hold an address of a character (36 bits in core2Duo), why we are putting a 'string' in it ?
The expression
char* filename="file.txt";
is a valid expression. Reason is type of a string literals in C ischar[N]
that can easily decay intochar*
, andchar[N]
andchar*
are compatible. Hence you can assign string address to achar*
pointer variable like you are doing in this expression.Why the compiler would not generate an error since you might be storing an address which can never exist?
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 likeint
,char
,float
.In case of basic data-types:
int i = 5; You are assigning value 5, to variable i char c = 'A'; You are assigning value 'A' to char variable c. float f = 5.5f; You are assigning value 5.5f to float variable f.
But for strings, when you do:
char* filename = "filename.txt";
Then you are actually assigning address of string
"filename.txt"
to char* pointer variablefilename
.Whereas if you do:
char filename[] = "filename.txt"; // ^ notice [] in declaration
Then you are assigning string "filename.txt"; to an array of char
filename[]
, herefilename
type ischar[]
.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.
(Whereasptr
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). InC
-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()函数;?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!