还在学习更多C并且有点困惑.在我的引用中,我发现有关分配尚未初始化的指针的注意事项.他们继续举例说明.昨天从帮助我指点的人那里得到了很好的答案,这里:
在跟进时,我简要地询问了循环的最后一次迭代,并可能将指针指向一个不存在的位置(即因为我的引用警告它).所以我回去看了一下,发现了这个:
如果你有一个指针
int *pt;
Run Code Online (Sandbox Code Playgroud)
然后在不初始化的情况下使用它(即我认为这意味着没有声明*pt= &myVariable
):
*pt = 606;
Run Code Online (Sandbox Code Playgroud)
你可能最终得到一个真正的糟糕的一天,取决于这个指针被分配给内存的位置.我遇到麻烦的部分是使用一串字符时这样的东西就可以了:
char *str = "Sometimes I feel like I'm going crazy.";
Run Code Online (Sandbox Code Playgroud)
引用所在的位置,"不要担心字符串在内存中的位置分配;它由编译器自动处理".所以没必要说初始化*str = &str[0];
或*str = str;
.意思是,编译器是自动char str[n];
在后台吗?
为什么处理方式不同?或者,我完全误解了吗?
dbu*_*ush 22
在这种情况下:
char *str = "Sometimes I feel like I'm going crazy.";
Run Code Online (Sandbox Code Playgroud)
您正在初始化str
以包含给定字符串文字的地址.此时你实际上并没有解除引用任何东西.
这也没关系:
char *str;
str = "Sometimes I feel like I'm going crazy.";
Run Code Online (Sandbox Code Playgroud)
因为您正在分配str
而不是实际解除引用它.
这是个问题:
int *pt;
*pt = 606;
Run Code Online (Sandbox Code Playgroud)
因为pt
没有初始化然后它被解除引用.
您也不能出于同样的原因(加上类型不匹配):
*pt= &myVariable;
Run Code Online (Sandbox Code Playgroud)
但你可以这样做:
pt= &myVariable;
Run Code Online (Sandbox Code Playgroud)
之后你可以自由使用*pt
.
Jos*_*ica 16
当你写作时sometype *p = something;
,它相当于sometype *p; p = something;
,而不是sometype *p; *p = something;
.这意味着当你使用这样的字符串文字时,编译器会找出放置它的位置,然后将其地址放在那里.
该声明
char *str = "Sometimes I feel like I'm going crazy.";
Run Code Online (Sandbox Code Playgroud)
相当于
char *str;
str = "Sometimes I feel like I'm going crazy.";
Run Code Online (Sandbox Code Playgroud)
P__*_*J__ 11
简化字符串文字可以表示为:
const char literal[] = "Sometimes I feel like I'm going crazy.";
Run Code Online (Sandbox Code Playgroud)
所以表达
char *str = "Sometimes I feel like I'm going crazy.";
Run Code Online (Sandbox Code Playgroud)
在逻辑上等同于:
const char literal[] = "Sometimes I feel like I'm going crazy.";
const char *str = literal;
Run Code Online (Sandbox Code Playgroud)
当然文字没有名字.
但是你不能取消引用没有为实际对象分配内存的char指针.
/* Wrong */
char *c;
*c = 'a';
/* Wrong - you assign the pointer with the integer value */
char *d = 'a';
/* Correct */
char *d = malloc(1);
*d = 'a';
/* Correct */
char x
char *e = &x;
*e = 'b';
Run Code Online (Sandbox Code Playgroud)
最后一个例子:
/* Wrong - you assign the pointer with the integer value */
int *p = 666;
/* Wrong you dereference the pointer which references to the not allocated space */
int *r;
*r = 666;
/* Correct */
int *s = malloc(sizeof(*s));
*s = 666;
/* Correct */
int t;
int *u = &t;
*u = 666;
Run Code Online (Sandbox Code Playgroud)
最后一个 - 类似于字符串文字=复合文字:
/* Correct */
int *z = (int[]){666,567,234};
z[2] = 0;
*z = 5;
/* Correct */
int *z = (const int[]){666,567,234};
Run Code Online (Sandbox Code Playgroud)
提出这个例子的好工作.它很好地显示了声明指针(如char *text;
)和指定指针(如)之间的区别text = "Hello, World!";
.
当你写:
char *text = "Hello!";
Run Code Online (Sandbox Code Playgroud)
它基本上与说:
char *text; /* Note the '*' before text */
text = "Hello!"; /* Note that there's no '*' on this line */
Run Code Online (Sandbox Code Playgroud)
(你知道,第一行也可以写成char* text;
.)
那么为什么*
二线上没有?因为text
是类型char*
,并且"你好!" 也是类型char*
.这里没有分歧.
此外,就编译器而言,以下三行是相同的:
char *text = "Hello!";
char* text = "Hello!";
char * text = "Hello!";
Run Code Online (Sandbox Code Playgroud)
在之前或之后放置空间*
没有区别.第二行可以说是更易于阅读,因为它驱动点回家的text
是一个char*
.(但要小心!如果你在一行上声明多个变量,这种风格会烧掉你!)
至于:
int *pt;
*pt = 606; /* Unsafe! */
Run Code Online (Sandbox Code Playgroud)
你可能会说*pt
是一个int
,所以是606
的,但它更准确的说,pt
(没有*
)是一个指针到内存是应该包含一个INT.而*pt
(带有a *
)引用内存中的intpt
(没有*
)指向.
而且由于pt
从未初始化,使用*pt
(分配或去引用)是不安全的.
现在,有关线条的有趣部分:
int *pt;
*pt = 606; /* Unsafe! */
Run Code Online (Sandbox Code Playgroud)
是他们会编译(尽管可能有警告).那是因为编译器看作*pt
是一个int
,也是606
一样int
,所以没有分歧.但是,如上所述,指针pt
不指向任何有效的内存,因此分配*pt
可能会导致崩溃,或损坏数据,或引发世界末日等.
认识到这一点很重要*pt
是不是一个变量(尽管它经常被用来像一个). *pt
只是指内存中包含地址的值pt
.因此,是否*pt
安全使用取决于是否pt
包含有效的内存地址.如果pt
未设置为有效内存,则使用*pt
不安全.
所以现在你可能想知道:宣布什么pt
是一个int*
而不仅仅是一个int
?
这取决于具体情况,但在很多情况下,没有任何意义.
在使用C和C++进行编程时,我使用了建议:如果您可以在不将其作为指针的情况下声明变量,那么您可能不应该将其声明为指针.
程序员经常在不需要时使用指针.当时,他们没有想到任何其他方式.根据我的经验,当它引起他们注意不使用指针时,他们会经常说不可能不使用指针.当我以其他方式证明它们时,它们通常会回溯并说它们的代码(使用指针)比不使用指针的代码更有效.
(但对于所有程序员来说都不是这样.有些人会认识到用非指针替换指针的吸引力和简单性,并乐意改变他们的代码.)
当然,我无法代表所有情况,但是现在C编译器通常足够聪明,可以编译指针代码和非指针代码,在效率方面几乎完全相同.不仅如此,根据具体情况,非指针代码通常比使用指针的代码更有效.
您的示例中混合了4个概念:
int *p;
或者char *str;
是指针的声明char *str = "some string";
声明指针并初始化它.str = "other string";
为指针赋值.类似地,p = (int*)606;
将606的值赋给指针.但是,在第一种情况下,该值是合法的,并指向字符串在静态内存中的位置.在第二种情况下,您可以为其分配任意地址p
.它可能是也可能不是合法地址.所以,p = &myint;
或者p = malloc(sizeof(int));
是更好的选择.*p = 606;
将值赋给'pointee'.现在它取决于指针'p'的值是否合法.如果你没有初始化指针,那就是非法的(除非你很幸运:-)). 归档时间: |
|
查看次数: |
1926 次 |
最近记录: |