需要c指针解释
关于指针,我是新手,有人能解释一下下面代码中输出的不同之处吗?在下面的代码中,我给一个3d指针赋值。作业结束后我把它们打印出来了。然后再把它们印成不同的版块。为什么输出会有所不同需要c指针解释,c,pointers,C,Pointers,关于指针,我是新手,有人能解释一下下面代码中输出的不同之处吗?在下面的代码中,我给一个3d指针赋值。作业结束后我把它们打印出来了。然后再把它们印成不同的版块。为什么输出会有所不同 #include<stdio.h> #define row 5 #define rw 3 #define col 10 char ***ptr,sh[10]; int i,j,k; int main() { ptr=(char *)malloc(row*sizeof(char *));
#include<stdio.h>
#define row 5
#define rw 3
#define col 10
char ***ptr,sh[10];
int i,j,k;
int main()
{
ptr=(char *)malloc(row*sizeof(char *));
for(i=0;i<row;i++)
{
*(ptr+i)=(char *)malloc(rw*sizeof(char *));
printf("\t:\n");
for(j=0;j<rw;j++)
{
*(*(ptr+i)+j)=(char *)malloc(col*sizeof(char *));
if(i==0 && j==0)
{
// *(*(ptr+row)+rw)="kabul";
**ptr="zapac";
}
else
{
sh[0]=i+48;
sh[1]=',';
sh[2]=j+48;
sh[3]='\0';
*(*(ptr+i)+j)=sh;
}
printf("\t%d%d = %s\n",i,j,ptr[i][j]);
}
printf("\n");
}
for(i=0;i<row;i++)
{
for(j=0;j<rw;j++)
{
printf("\t%d%d %s\n",i,j,ptr[i][j]);
}
printf("\n");
}
return 0;
}
我的问题是,为什么下面的输出与上面的不一致
00 zapac
01 4,2
02 4,2
10 4,2
11 4,2
12 4,2
20 4,2
21 4,2
22 4,2
30 4,2
31 4,2
32 4,2
40 4,2
41 4,2
42 4,2
因为sh[10]是全局定义的,当第一个循环打印此数组的当前值时(此数组的内容不保留),每次迭代都会更改。对于第二个循环,您将打印在第一个循环中写入的最后一个值(即在最后一次迭代中) 您最好在第一个循环的每次迭代中分配:
for(j=0;j<rw;j++)
{
*(*(ptr+i)+j)=(char *)malloc(col*sizeof(char *));
char* psh = (char*)malloc(10*sizeof(char));
if(i==0 && j==0)
{
strcpy(psh, "zapac");
}
else
{
psh[0]=i+48;
psh[1]=',';
psh[2]=j+48;
psh[3]='\0';
*(*(ptr+i)+j)=psh;
}
for(j=0;j获得输出的原因是您的*(*(ptr+i)+j)=sh
正在设置所有的char*
s(第一个除外,您专门处理过)同一个值,这是sh
中数组数据的地址。只有一个sh
副本,它的数组数据的一个副本;所有char*
s都指向该单个副本。以后打印值时,您只是通过指向它的不同指针反复打印相同的数据副本,所以y您将获得上次修改时放入的内容,而不是设置指针时放入的内容
您可能希望每个char*
都获得数组的新副本,而不是仅仅指向sh
,但是如果这是您想要的,您必须自己复制数据
所以…如果您替换这一行:
*(*(ptr+i)+j)=sh;
比如:
*(*(ptr+i)+j)=malloc(sizeof(sh));
strcpy( *(*(ptr+i)+j), sh );
或
您将得到您期望的结果,因为每个char*
将指向复制时sh
中的字符串的新副本。不过,您需要记住稍后释放它们以及malloc()
ed中的所有内容
大多数malloc()
行也不正确,但由于char*
、char**
和char***
在系统上可能大小相同,因此它仍然可以工作
ptr=(char *)malloc(row*sizeof(char *));
应该是
ptr = (char ***)malloc(row*sizeof(char **));
*(ptr+i)=(char **)malloc(rw*sizeof(char *));
由于您正在分配一个char**
(指针指向char
)数组,可通过char***
(指针指向char
)访问该数组。同样:
*(ptr+i)=(char *)malloc(rw*sizeof(char *));
应该是
ptr = (char ***)malloc(row*sizeof(char **));
*(ptr+i)=(char **)malloc(rw*sizeof(char *));
或
分配通过char**
(指向char
的指针)访问的char*
(指向char
的指针)数组
malloc()调用前面的强制转换实际上是可选的--malloc()
的void*
结果将被转换为您分配给它的任何指针类型。但是,在这种情况下,强制转换应该会使编译器警告您类型错误。@Dmitri关于您看到的症状的原因是正确的,但是代码中还有其他问题,一些严重的,有些则不然
这是你的程序的修改版本
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define ROW 5
#define RW 3
#define COL 10
int main(void)
{
char ***ptr;
char sh[10];
ptr = malloc(ROW * sizeof *ptr);
for (int i = 0; i < ROW; i++)
{
ptr[i] = malloc(RW * sizeof *(ptr[i]));
printf("\t:\n");
for (int j = 0; j < RW; j++)
{
ptr[i][j] = malloc(COL * sizeof *(ptr[i][j]));
if (i==0 && j==0)
{
// *(*(ptr+ROW)+RW) = "kabul";
ptr[i][j] = "zapac";
}
else
{
sh[0] = '0' + i;
sh[1] = ',';
sh[2] = '0' + j;
sh[3] = '\0';
// ptr[i][j] = sh;
strcpy(ptr[i][j], sh);
}
// printf("\t%d%d = %s\n", i, j, ptr[i][j]);
printf("\tptr[%d][%d] = \"%s\"\n", i, j, ptr[i][j]);
}
printf("\n");
}
for (int i = 0; i < ROW; i++)
{
for (int j = 0; j < RW; j++)
{
// printf("\t%d%d %s\n", i, j, ptr[i][j]);
printf("\tptr[%d][%d] = \"%s\"\n", i, j, ptr[i][j]);
}
printf("\n");
}
return 0;
}
#包括
#包括
#包括
#定义第5行
#定义RW3
#定义第10列
内部主(空)
{
字符***ptr;
char-sh[10];
ptr=malloc(行*sizeof*ptr);
对于(int i=0;i|
我所做的更改是:
添加#include
以获取malloc()的声明。这不是可选的(尽管编译器可能允许您忽略它)。如果没有#include
,C99之前的编译器将假定malloc()
返回一个int
;这会导致未定义的行为。这意味着可能会发生任意不好的事情,或者可能会发生在某些系统上
遵循宏使用所有caps名称的常规
添加一些空格(我发现它使代码更清晰,尤其是在每个逗号后面和大多数运算符周围都有空格)
使变量成为局部变量而不是全局变量
在各自的循环中声明循环控制变量。这是C99特有的功能,但您的编译器可能支持它。(对于gcc,请使用gcc-std=C99
)
修复malloc()
调用,根据指针指向的大小计算大小
使用索引运算符而不是显式指针算法。通常,x[y]
表示*(x+y)
,因此,例如,*(*(ptr+i)+j)
可以简单地写成ptr[i][j]
使用strcpy()
将存储在sh
中的字符串复制到ptr[i][j]指向的字符串中,而不仅仅是复制指针。(这解决了Dmitri已经发现的问题;您可能应该接受他的答案,因为他首先提到了这个问题。)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define ROW 5
#define RW 3
#define COL 10
int main(void)
{
char ***ptr;
char sh[10];
ptr = malloc(ROW * sizeof *ptr);
for (int i = 0; i < ROW; i++)
{
ptr[i] = malloc(RW * sizeof *(ptr[i]));
printf("\t:\n");
for (int j = 0; j < RW; j++)
{
ptr[i][j] = malloc(COL * sizeof *(ptr[i][j]));
if (i==0 && j==0)
{
// *(*(ptr+ROW)+RW) = "kabul";
ptr[i][j] = "zapac";
}
else
{
sh[0] = '0' + i;
sh[1] = ',';
sh[2] = '0' + j;
sh[3] = '\0';
// ptr[i][j] = sh;
strcpy(ptr[i][j], sh);
}
// printf("\t%d%d = %s\n", i, j, ptr[i][j]);
printf("\tptr[%d][%d] = \"%s\"\n", i, j, ptr[i][j]);
}
printf("\n");
}
for (int i = 0; i < ROW; i++)
{
for (int j = 0; j < RW; j++)
{
// printf("\t%d%d %s\n", i, j, ptr[i][j]);
printf("\tptr[%d][%d] = \"%s\"\n", i, j, ptr[i][j]);
}
printf("\n");
}
return 0;
}