C 为什么它们都指向同一个地方?
为什么它们都指向同一个地方?这是一个优化C 为什么它们都指向同一个地方?,c,pointers,string-literals,C,Pointers,String Literals,为什么它们都指向同一个地方?这是一个优化 #include <stdio.h> #include <stdlib.h> #include <stdint.h> #include <time.h> #include <conio.h> const char* func1(const char str[]){ // printf("%p\n", str); return str; } const char* func2(co
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <time.h>
#include <conio.h>
const char* func1(const char str[]){
// printf("%p\n", str);
return str;
}
const char* func2(const char *str){
// printf("%p\n", str);
return str;
}
char* func3(char str[]){
// printf("%p\n", str);
return str;
}
char* func4(char *str){
// printf("%p\n", str);
return str;
}
int main(void)
{
char acStr[81] = {0};
const char *p1, *p2;
char *p3, *p4;
uint32_t uiCount;
srand (time(NULL));
for(uiCount = 0; uiCount < (sizeof(acStr) - 1); uiCount++){
acStr[uiCount] = rand() % 26 + 65;
}
acStr[80] = 0;
p1 = func1(acStr);
printf("p1 == %p\n", p1);
printf("%s", p1);
for(uiCount = 0; uiCount < (sizeof(acStr) - 1); uiCount++){
acStr[uiCount] = rand() % 26 + 65;
}
acStr[80] = 0;
p2 = func2(acStr);
printf("p2 == %p\n", p2);
printf("%s", p2);
for(uiCount = 0; uiCount < (sizeof(acStr) - 1); uiCount++){
acStr[uiCount] = rand() % 26 + 65;
}
acStr[80] = 0;
p3 = func3(acStr);
printf("p3 == %p\n", p3);
printf("%s", p3);
for(uiCount = 0; uiCount < (sizeof(acStr) - 1); uiCount++){
acStr[uiCount] = rand() % 26 + 65;
}
acStr[80] = 0;
p4 = func4(acStr);
printf("p4 == %p\n", p4);
printf("%s", p4);
printf("\n");
printf("p1 == %p\n", p1); /* Same address */
printf("%s", p1);
printf("p2 == %p\n", p2); /* Same address */
printf("%s", p2);
printf("p3 == %p\n", p3); /* Same address */
printf("%s", p3);
printf("p4 == %p\n", p4); /* Same address */
printf("%s", p4);
getch();
return 0;
}
#包括
#包括
#包括
#包括
#包括
常量字符*func1(常量字符字符串[]){
//printf(“%p\n”,str);
返回str;
}
常量字符*func2(常量字符*str){
//printf(“%p\n”,str);
返回str;
}
char*func3(char str[]{
//printf(“%p\n”,str);
返回str;
}
char*func4(char*str){
//printf(“%p\n”,str);
返回str;
}
内部主(空)
{
char acStr[81]={0};
常量字符*p1,*p2;
字符*p3,*p4;
uint32\u t uiCount;
srand(时间(空));
对于(uiCount=0;uiCount<(sizeof(acStr)-1);uiCount++){
acStr[uiCount]=rand()%26+65;
}
acStr[80]=0;
p1=func1(acStr);
printf(“p1==%p\n”,p1);
printf(“%s”,p1);
对于(uiCount=0;uiCount<(sizeof(acStr)-1);uiCount++){
acStr[uiCount]=rand()%26+65;
}
acStr[80]=0;
p2=func2(acStr);
printf(“p2==%p\n”,p2);
printf(“%s”,p2);
对于(uiCount=0;uiCount<(sizeof(acStr)-1);uiCount++){
acStr[uiCount]=rand()%26+65;
}
acStr[80]=0;
p3=func3(acStr);
printf(“p3==%p\n”,p3);
printf(“%s”,p3);
对于(uiCount=0;uiCount<(sizeof(acStr)-1);uiCount++){
acStr[uiCount]=rand()%26+65;
}
acStr[80]=0;
p4=func4(acStr);
printf(“p4==%p\n”,p4);
printf(“%s”,p4);
printf(“\n”);
printf(“p1==%p\n”,p1);/*相同地址*/
printf(“%s”,p1);
printf(“p2==%p\n”,p2);/*相同地址*/
printf(“%s”,p2);
printf(“p3==%p\n”,p3);/*相同地址*/
printf(“%s”,p3);
printf(“p4==%p\n”,p4);/*相同地址*/
printf(“%s”,p4);
getch();
返回0;
}
输出
p1 == 000000000022FDC0
USOPBBREKRTCCAXRFVPJPEVPESVTAIQUXIPNMCAWHZGWWUSUUNCWNGFRCTHLJLANVSRQJCTCOOXQZIYX
p2 == 000000000022FDC0
SVITQWBDXTQSUJKXIUKIANTUELJCJPVDYEBCIDGDWITCTZJTDERRPINICWNSIIKMAVTFKIUHEEGNEKBD
p3 == 000000000022FDC0
IDTZXTQWPSRURMWBCAKXWKXJANLVHRDMDREGKBYKJZMDHYHSGRMYAAAGWWRWSAJMBYODZYBKMYPPMVXN
p4 == 000000000022FDC0
TFCBRYSYRNNDUEEOQAPMAGOVQKYNIKNGOQJSBFKYTVRIGWHZMCLFNASRRSGDZWIXOVKYBRYPQOEXRFUJ
p1 == 000000000022FDC0
TFCBRYSYRNNDUEEOQAPMAGOVQKYNIKNGOQJSBFKYTVRIGWHZMCLFNASRRSGDZWIXOVKYBRYPQOEXRFUJ
p2 == 000000000022FDC0
TFCBRYSYRNNDUEEOQAPMAGOVQKYNIKNGOQJSBFKYTVRIGWHZMCLFNASRRSGDZWIXOVKYBRYPQOEXRFUJ
p3 == 000000000022FDC0
TFCBRYSYRNNDUEEOQAPMAGOVQKYNIKNGOQJSBFKYTVRIGWHZMCLFNASRRSGDZWIXOVKYBRYPQOEXRFUJ
p4 == 000000000022FDC0
TFCBRYSYRNNDUEEOQAPMAGOVQKYNIKNGOQJSBFKYTVRIGWHZMCLFNASRRSGDZWIXOVKYBRYPQOEXRFUJ
p1==0000000000 22FDC0
USOPBBREKRTCAXSRFVPJPEVPESVTAIQUXIPNMCAWZGWWWWWWWWWWGFRCTHLJLLANVSRQJCTCOXQZIYX
p2==0000000000 22fdc0
SVITQWBDXTQSUJKXIUKIANTUELJCJPVDYEBCIDGWITCTZJTDERRPINICWNSIIKMAVTFKIUHEEGNEKBD
p3==0000000000 22fdc0
IDTZXTQWPSRURMWBCAKXWKXJANLVRDMDREGKBYKJZMDHYHSGRMYAAAGWWRWSAJMBYDZYBKYPmVxN
p4==0000000000 22fdc0
TFCBRYSYRNDUEEOQAPMAGOVQKYNIKNGOQJSBFKYTVRIGWHZMCLFNASRSGDZWIXOVKYPBRQOEXRFUJ
p1==0000000000 22FDC0
TFCBRYSYRNDUEEOQAPMAGOVQKYNIKNGOQJSBFKYTVRIGWHZMCLFNASRSGDZWIXOVKYPBRQOEXRFUJ
p2==0000000000 22fdc0
TFCBRYSYRNDUEEOQAPMAGOVQKYNIKNGOQJSBFKYTVRIGWHZMCLFNASRSGDZWIXOVKYPBRQOEXRFUJ
p3==0000000000 22fdc0
TFCBRYSYRNDUEEOQAPMAGOVQKYNIKNGOQJSBFKYTVRIGWHZMCLFNASRSGDZWIXOVKYPBRQOEXRFUJ
p4==0000000000 22fdc0
TFCBRYSYRNDUEEOQAPMAGOVQKYNIKNGOQJSBFKYTVRIGWHZMCLFNASRSGDZWIXOVKYPBRQOEXRFUJ
我不清楚,因为我不会说英语
(由Google translante翻译)在4个函数中,您返回的指针与作为参数传递的指针相同,因此它不会改变。它仍然指向相同的
acStr
变量
将const
添加到参数类型不会创建副本;它只是阻止您更改其内容
在这种情况下,
str[]
和*str
也是相同的。所有函数都返回其参数的值;在所有四种情况下,函数都接收acStr
的第一个元素的地址
您不会在每次调用之间更改存储acStr
的位置;您只是在更改acStr
包含的内容
我获取了您的代码,并添加了一些调用来转储变量的内存映射。以下是在调用func1
之前,一开始的情况:
Item Address 00 01 02 03
---- ------- -- -- -- --
acStr 0x7fff5bfde5b0 00 00 00 00 ....
0x7fff5bfde5b4 00 00 00 00 ....
0x7fff5bfde5b8 00 00 00 00 ....
0x7fff5bfde5bc 00 00 00 00 ....
0x7fff5bfde5c0 00 00 00 00 ....
0x7fff5bfde5c4 00 00 00 00 ....
0x7fff5bfde5c8 00 00 00 00 ....
0x7fff5bfde5cc 00 00 00 00 ....
0x7fff5bfde5d0 00 00 00 00 ....
0x7fff5bfde5d4 00 00 00 00 ....
0x7fff5bfde5d8 00 00 00 00 ....
0x7fff5bfde5dc 00 00 00 00 ....
0x7fff5bfde5e0 00 00 00 00 ....
0x7fff5bfde5e4 00 00 00 00 ....
0x7fff5bfde5e8 00 00 00 00 ....
0x7fff5bfde5ec 00 00 00 00 ....
0x7fff5bfde5f0 00 00 00 00 ....
0x7fff5bfde5f4 00 00 00 00 ....
0x7fff5bfde5f8 00 00 00 00 ....
0x7fff5bfde5fc 00 00 00 00 ....
0x7fff5bfde600 00 10 40 00 ..@.
p1 0x7fff5bfde5a8 00 80 0f 5c ...\
0x7fff5bfde5ac c1 2a 00 00 .*..
p2 0x7fff5bfde5a0 80 e6 fd 5b ...[
0x7fff5bfde5a4 ff 7f 00 00 ....
p3 0x7fff5bfde598 48 83 0f 5c H..\
0x7fff5bfde59c c1 2a 00 00 .*..
p4 0x7fff5bfde590 00 00 00 00 ....
0x7fff5bfde594 01 00 00 00 ....
数组对象acStr
从地址0x7fff5bfde5b0
开始;您已初始化它,使其包含所有零。指针变量p1开始于地址0x7fff5bfde5a8,p2开始于地址0x7fff5bfde5a0,等等。请注意,编译器不必按照声明对象的相同顺序排列单独的对象
p1
、p2
、p3
和p4
中的每一个最初都包含一个不确定的值;它们没有特别指向任何物体。在此阶段尝试取消引用其中的每一个将导致未定义的行为
调用func1
后,对象如下所示:
Item Address 00 01 02 03
---- ------- -- -- -- --
acStr 0x7fff5bfde5b0 4f 48 5a 5a OHZZ
0x7fff5bfde5b4 57 53 46 4b WSFK
0x7fff5bfde5b8 59 49 52 52 YIRR
0x7fff5bfde5bc 49 51 48 4e IQHN
0x7fff5bfde5c0 50 43 54 56 PCTV
0x7fff5bfde5c4 50 53 4d 5a PSMZ
0x7fff5bfde5c8 52 53 46 49 RSFI
0x7fff5bfde5cc 4b 50 50 59 KPPY
0x7fff5bfde5d0 5a 51 58 56 ZQXV
0x7fff5bfde5d4 4a 44 49 4a JDIJ
0x7fff5bfde5d8 4e 5a 41 56 NZAV
0x7fff5bfde5dc 50 48 49 47 PHIG
0x7fff5bfde5e0 4c 45 42 42 LEBB
0x7fff5bfde5e4 59 50 43 50 YPCP
0x7fff5bfde5e8 48 4a 58 52 HJXR
0x7fff5bfde5ec 41 4f 53 5a AOSZ
0x7fff5bfde5f0 46 50 58 51 FPXQ
0x7fff5bfde5f4 55 46 5a 4a UFZJ
0x7fff5bfde5f8 45 42 47 56 EBGV
0x7fff5bfde5fc 4b 52 42 57 KRBW
0x7fff5bfde600 00 10 40 00 ..@.
p1 0x7fff5bfde5a8 b0 e5 fd 5b ...[
0x7fff5bfde5ac ff 7f 00 00 ....
p2 0x7fff5bfde5a0 80 e6 fd 5b ...[
0x7fff5bfde5a4 ff 7f 00 00 ....
p3 0x7fff5bfde598 48 83 0f 5c H..\
0x7fff5bfde59c c1 2a 00 00 .*..
p4 0x7fff5bfde590 00 00 00 00 ....
0x7fff5bfde594 01 00 00 00 ....
acStr
的内容已修改,但其地址保持不变。类似地,p1
的内容已经修改;它现在包含acStr
(x86以小尾端顺序存储多字节值,因此它们读取“向后”)
调用func2
后,我们有
Item Address 00 01 02 03
---- ------- -- -- -- --
acStr 0x7fff5bfde5b0 56 45 5a 54 VEZT
0x7fff5bfde5b4 56 42 4a 44 VBJD
0x7fff5bfde5b8 4b 49 57 4b KIWK
0x7fff5bfde5bc 5a 51 4d 45 ZQME
0x7fff5bfde5c0 49 4a 57 43 IJWC
0x7fff5bfde5c4 4f 58 4d 55 OXMU
0x7fff5bfde5c8 59 53 50 49 YSPI
0x7fff5bfde5cc 4a 53 47 47 JSGG
0x7fff5bfde5d0 57 46 41 52 WFAR
0x7fff5bfde5d4 47 4a 57 53 GJWS
0x7fff5bfde5d8 54 56 46 53 TVFS
0x7fff5bfde5dc 4e 52 59 56 NRYV
0x7fff5bfde5e0 41 55 59 51 AUYQ
0x7fff5bfde5e4 52 4d 4b 52 RMKR
0x7fff5bfde5e8 47 42 43 53 GBCS
0x7fff5bfde5ec 56 49 41 54 VIAT
0x7fff5bfde5f0 51 41 4d 59 QAMY
0x7fff5bfde5f4 4c 4c 52 46 LLRF
0x7fff5bfde5f8 49 57 58 56 IWXV
0x7fff5bfde5fc 50 57 52 50 PWRP
0x7fff5bfde600 00 10 40 00 ..@.
p1 0x7fff5bfde5a8 b0 e5 fd 5b ...[
0x7fff5bfde5ac ff 7f 00 00 ....
p2 0x7fff5bfde5a0 b0 e5 fd 5b ...[
0x7fff5bfde5a4 ff 7f 00 00 ....
p3 0x7fff5bfde598 48 83 0f 5c H..\
0x7fff5bfde59c c1 2a 00 00 .*..
p4 0x7fff5bfde590 00 00 00 00 ....
0x7fff5bfde594 01 00 00 00 ....
再次修改了acStr
的内容,但其地址保持不变。现在p2
和p1
都包含该地址的副本
对
func3
和func4
的调用也会发生同样的情况;它们返回输入的地址,在两次调用之间不会改变。该地址值被复制到p3
和p4
中的每一个 因为你每次都传递相同的东西?你到底期望什么?不同的指针具有不同的函数,并且总是生成相同的地址,那么我就失去了previous的值…只有一个字符串。每个函数都返回传递给它的内容,即相同的字符串。您在每次调用之间更改了字符串的内容,但字符串仍然是相同的,位于内存中的相同位置。您将数组传递给函数。数组衰减为指针,然后返回该指针。这4个功能中的任何一个都没有区别,它们是相同的。您传递相同的数组,然后返回相同的内容;然后生成一个副本。另一种方法是通过引用传递。在这种情况下,返回的指针将不同(除非您仍然传递4个相同的内容,并且编译器选项合并重复项)