鱼C论坛

 找回密码
 立即注册
查看: 3074|回复: 21

[已解决]求助 如何用指针给二维数组赋值

[复制链接]
发表于 2019-1-10 09:47:06 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
void cleanChessboard(char *CB,int n){
        int i,j;
        for(i = 0;i < n;i++){
                for(j = 0;j < n;j++){
                        *(CB + i) + j = '*';
                        printf("%c",*(CB + i) + j);
                }
        }
}
这其中 *(CB + i) + j = '*'; 报错是        [Error] lvalue required as left operand of assignment
请问大佬们 *(CB + i) + j 与 cb【i】【j】(假定这个是指针指向的那个数组)一样么?请大佬说的详细一些。感激不尽。
最佳答案
2019-1-13 12:01:48
#include <stdio.h>
void addBlack(int n,int m);
void addWhite(int n,int m);
void cleanChessBoard(char* CB,int n);
void judge(void);
char chessBoard[14][14];        //全局变量chessBoard[14][14]已定义
int main(){
        char* CB;
        //char chessBoard[14][14];        //chessBoard已定义为全局变量,你cleanChessBoard(char* CB,int n);函数体中的打印也是操作的全局变量

        //CB = &chessBoard[14][14];        //这样取地址根本就不对,chessBoard[14][14]代表的是第15行第15个元素,而你数组下表是0~13。这里你一定要加强理解。
                                                                        //如果你本意想取整个数组的地址,这样你需要定义CB为char(*) [14][14]类型,即定义为char(*CB) [14][14] = &chessBoard;
                //CB = (char*) &chessBoard;        //如果你就是很执着的想,CB定义为char* CB;,而又要通过CB=&chessBoard;来获取地址,
                                                                        //那么你可以修改为CB = (char *)&chessBoard;,这样就强制转换了指针类型。



                                                                        //CB为char* 类型,你是想取得是数组的首地址,所以应该修改为:
                CB = &chessBoard[0][0];                //CB指向全局变量的第一个元素,这时CB只知道它指向的是一个char元素,不知道指向的是一个数组

        cleanChessBoard(CB,14);
        return 0;
}
//void cleanChessboard(char* CB,int n){        //函数名定义字母写错大写的B写成了小写的b
void cleanChessBoard(char* CB,int n){

        int i,j;
        for(i = 0;i < n;i++){
                        for(j = 0;j < n;j++){
                                if(i == 0 ){
                                        //*(*(CB + i) + j) = (char)j ;        //用这种二维数组的指针直接作为参数传递时,
                                                                                                        //数组名退化为指针,函数并不知道数组的列数,
                                                                                                        //n对它来说是不可见的,即便使用*(*(CB + i) + j)。第一层解引用失败

                                        //为了指导这个函数如何解引用,也就是要人为地解引用,需要把这个二维数组的首元素地址传给函数,
                                        //于是就变成了下面的形式:
                                        *((CB + i*n) + j) = (char)j ;

                                }
                                else{
                                        //*(*(CB + i) + j) = '*'        //这段代码结束缺少结束“;”号。同上也需要人为地解引用
                                        *((CB + i*n) + j) = '*';
                                }
                                printf("%c",chessBoard[i][j]);        //这里打印的是全局变量chessBoard[i][j]
                                printf(" ");
                        }
        }
}
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2019-1-10 09:58:09 | 显示全部楼层
编译器是dev c++
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-1-10 15:22:53 | 显示全部楼层
我觉得应该是*(*(CB + i) + j) = '*'才可以,否则你等号左侧的不是你要赋的值,而是一个表达式,自然就报等号左边的值不是变量的错误了
而且你那个CB应该是一个二维数组 **CB,或者*CB[N]
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-1-10 17:01:41 | 显示全部楼层
二维数组作为形参不能只写 一个 *
二维数组取值需要两个*,所以3#的方式应该ok
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-1-10 19:46:42 | 显示全部楼层
首先来说,用指针指向一个二维数组,说白了就是有这个二维数组的地址,接下来对这个指针进行一层的解引用

也就是 * ,那么得到的就是这个二维数组,但是你想获得的是这个二维数组里面某一个具体的位置的值,那么肯

定就要再进行一层解引用才可以。你的第二个问题的话,如果大写的CB是指向数组的指针,而小写的cb是数组名

的话,那是不一样的。如果这两个都是一个指向二维数组的指针的话,那应该这两种写法都是会报错的
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-1-12 15:53:19 | 显示全部楼层
boqianlv 发表于 2019-1-10 15:22
我觉得应该是*(*(CB + i) + j) = '*'才可以,否则你等号左侧的不是你要赋的值,而是一个表达式,自然就报等 ...

我也试过用这种方法但是还是报错
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-1-12 16:15:25 | 显示全部楼层
#include <stdio.h>
void addBlack(int n,int m);
void addWhite(int n,int m);
void cleanChessBoard(char* CB,int n);
void judge(void);
char chessBoard[14][14];
int main(){
        char* CB;
        char chessBoard[14][14];
        CB = &chessBoard[14][14];
        cleanChessBoard(CB,14);
        return 0;
}
void cleanChessboard(char* CB,int n){
        int i,j;
        for(i = 0;i < n;i++){
                for(j = 0;j < n;j++){
                        if(i == 0 ){
                                *(*(CB + i) + j) = (char)j ;
                        }
                        else{
                                *(*(CB + i) + j) = '*'
                        }
                        printf("%c",chessBoard[i][j]);
                        printf(" ");
                }
        }
}
改进过了还是不行
[Error] invalid type argument of unary '*' (have 'int')
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-1-12 17:53:34 | 显示全部楼层
cookies945 发表于 2019-1-12 16:15
改进过了还是不行
[Error] invalid type argument of unary '*' (have 'int')

#include <iostream>
#include <string>

void func1(char *a,int b,int c);

int main()
{
        int n = 10 , m = 20;
        char a1[n][m];
        char *a = &a1[0][0];
//        for (int i = 0;i < 10 ; ++i)
//        {
//                std::cout << a + i << std::endl;
//        }
       
        func1(a, n,m);
        for (int i = 0; i <n ; ++i)
        {
                for(int j = 0; j < m ; ++j)
                {
                        std::cout << a1[i][j]<< std::endl;
                }
        }
       
       
        return 0 ;
}

void func1(char *a , int b , int c)
{
        for (int i = 0;i <b ; ++i)
        {
                for(int j = 0; j < c ; ++j)
                {
                        if (0 == i)
                        {
                                *(a + i *c + j) = (char)j;
                        }
                        else
                        {
                                *(a + i *c + j) =  '*';
                        }
                }
        }
}

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-1-13 09:39:19 | 显示全部楼层
cookies945 发表于 2019-1-12 16:15
改进过了还是不行
[Error] invalid type argument of unary '*' (have 'int')

你这个CB既然是二维数组,指针也要是二维的
还有你那个(char)j是什么意思,j是循环变量……转化为char也没意义啊
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-1-13 12:01:48 | 显示全部楼层    本楼为最佳答案   
#include <stdio.h>
void addBlack(int n,int m);
void addWhite(int n,int m);
void cleanChessBoard(char* CB,int n);
void judge(void);
char chessBoard[14][14];        //全局变量chessBoard[14][14]已定义
int main(){
        char* CB;
        //char chessBoard[14][14];        //chessBoard已定义为全局变量,你cleanChessBoard(char* CB,int n);函数体中的打印也是操作的全局变量

        //CB = &chessBoard[14][14];        //这样取地址根本就不对,chessBoard[14][14]代表的是第15行第15个元素,而你数组下表是0~13。这里你一定要加强理解。
                                                                        //如果你本意想取整个数组的地址,这样你需要定义CB为char(*) [14][14]类型,即定义为char(*CB) [14][14] = &chessBoard;
                //CB = (char*) &chessBoard;        //如果你就是很执着的想,CB定义为char* CB;,而又要通过CB=&chessBoard;来获取地址,
                                                                        //那么你可以修改为CB = (char *)&chessBoard;,这样就强制转换了指针类型。



                                                                        //CB为char* 类型,你是想取得是数组的首地址,所以应该修改为:
                CB = &chessBoard[0][0];                //CB指向全局变量的第一个元素,这时CB只知道它指向的是一个char元素,不知道指向的是一个数组

        cleanChessBoard(CB,14);
        return 0;
}
//void cleanChessboard(char* CB,int n){        //函数名定义字母写错大写的B写成了小写的b
void cleanChessBoard(char* CB,int n){

        int i,j;
        for(i = 0;i < n;i++){
                        for(j = 0;j < n;j++){
                                if(i == 0 ){
                                        //*(*(CB + i) + j) = (char)j ;        //用这种二维数组的指针直接作为参数传递时,
                                                                                                        //数组名退化为指针,函数并不知道数组的列数,
                                                                                                        //n对它来说是不可见的,即便使用*(*(CB + i) + j)。第一层解引用失败

                                        //为了指导这个函数如何解引用,也就是要人为地解引用,需要把这个二维数组的首元素地址传给函数,
                                        //于是就变成了下面的形式:
                                        *((CB + i*n) + j) = (char)j ;

                                }
                                else{
                                        //*(*(CB + i) + j) = '*'        //这段代码结束缺少结束“;”号。同上也需要人为地解引用
                                        *((CB + i*n) + j) = '*';
                                }
                                printf("%c",chessBoard[i][j]);        //这里打印的是全局变量chessBoard[i][j]
                                printf(" ");
                        }
        }
}
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-1-13 12:03:39 | 显示全部楼层
本帖最后由 行客 于 2019-1-13 18:37 编辑

请好好的看看我做的注释,最好复制到你的编译器里再看,这样可以看的更清楚。

我感觉已经说得足够明白,2个来小时写出的成果,希望认真看啊。

有疑问请继续跟帖。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-1-14 10:18:14 | 显示全部楼层
boqianlv 发表于 2019-1-13 09:39
你这个CB既然是二维数组,指针也要是二维的
还有你那个(char)j是什么意思,j是循环变量……转化为char也 ...

第一行要输出棋盘的横竖的坐标
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-1-14 10:30:58 | 显示全部楼层
行客 发表于 2019-1-13 12:03
请好好的看看我做的注释,最好复制到你的编译器里再看,这样可以看的更清楚。

我感觉已经说得足够明白, ...

感谢大佬,讲的很详细,但是还是有一点疑问,就是
    //*(*(CB + i) + j) = (char)j ;        //用这种二维数组的指针直接作为参数传递时,
                                                                                                        //数组名退化为指针,函数并不知道数组的列数,
                                                                                                        //n对它来说是不可见的,即便使用*(*(CB + i) + j)。第一层解引用失败

                                        //为了指导这个函数如何解引用,也就是要人为地解引用,需要把这个二维数组的首元素地址传给函数,
                                        //于是就变成了下面的形式:
                                        *((CB + i*n) + j) = (char)j ;
是不是只有用指针指向二维数组才需要人为解引用,而使用数组名就不需要呢,我在网上找的资料,还有小甲鱼的二维数组与指针的课堂上都没有看见有关这一类的解释,希望大佬说一说要在什么时候解引用,什么时候要人为解引用,谢谢,谢谢!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-1-14 13:59:02 | 显示全部楼层
本帖最后由 行客 于 2019-1-14 14:13 编辑

这里注明一下原创啊,有转载或借鉴的,请注明来源及作者:行客。

加个隐藏吧,看看除了VIP外有谁都看过。

游客,如果您要查看本帖隐藏内容请回复
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-1-15 10:41:52 | 显示全部楼层
啊涂涂 发表于 2019-1-10 19:46
首先来说,用指针指向一个二维数组,说白了就是有这个二维数组的地址,接下来对这个指针进行一层的解引用
...

那是应该用&取址在赋值么?
就是CB = & chessBoard;
这样么
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-1-15 10:57:36 | 显示全部楼层
行客 发表于 2019-1-14 13:59
这里注明一下原创啊,有转载或借鉴的,请注明来源及作者:行客。

加个隐藏吧,看看除了VIP外 ...

感谢大佬耐心解答,还是有一些疑问。

printf("%#X\n",&arry);0X62FE20
printf("%#X\n",&arry+1)0X62FE38
printf("%#X\n",arry+1);0X62FE2C
printf("%#X\n",sizeof(int));0X4

这是不是可以理解为&arry包括了整个数组,而arry就只是这个数组的一行而已呢?
还有就是想请教一下,

int array[2][3]={{0,1,2},{3,4,5}};
int (*p)[3] = array;

这是不是就是每个p指向的都是array的一行呀?
这个是小甲鱼在视频里的例子,他在视频使用*(*p+10+2)的方法来找到array[1][2],没有报错,也是没有人为解引用的,请问这是编译器的原因么,为什么我这样写:

char chessBoard[14][14];
char (*CB)[14] = chessBoard;
*(*(CB + 1)+2) = '*';
需要使用人为的解引用呢,是编译器的问题么,还是因为我是定义在main函数里,又在其他函数里调用它的原因呢?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-1-15 11:15:09 | 显示全部楼层
cookies945 发表于 2019-1-15 10:57
感谢大佬耐心解答,还是有一些疑问。

printf("%#X\n",&arry);0X62FE20

1、这是不是可以理解为&arry包括了整个数组,而arry就只是这个数组的一行而已呢?
还有就是想请教一下,
回复:是的,就是这样。你可以这样去理解:&array代表整个二维数组地址,array代表一行地址,*array代表一个元素地址。

2、抱歉,小甲鱼的视频我没有看。人为的解引用和编译器没有关系,也和你说的main函数定位在里面没有关系。之所以你会这样问,是因为你对上面我所说的还没看明白。请再仔细看一下。

如还有疑问请继续跟帖。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-1-15 11:16:38 | 显示全部楼层
cookies945 发表于 2019-1-15 10:41
那是应该用&取址在赋值么?
就是CB = & chessBoard;
这样么

不好意思兄弟,回复太多天了,代码也看不懂你写的意思了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-1-16 13:17:02 | 显示全部楼层
啊涂涂 发表于 2019-1-15 11:16
不好意思兄弟,回复太多天了,代码也看不懂你写的意思了

好的把没事
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-1-16 13:24:40 | 显示全部楼层
行客 发表于 2019-1-15 11:15
1、这是不是可以理解为&arry包括了整个数组,而arry就只是这个数组的一行而已呢?
还有就是想请教一下, ...


这是不是可以理解为我定义的指针类型不一样
char* 是定义字符指针,而(char*) []定义的是数组指针,所以指针需要人为的解引用,而数组指针却不用,是么?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-10-3 04:35

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表