指针 数组 退化问题

CXDN假专家能不能少点 2013-02-26 01:33:07
数组退化成指针以后,好像是没办法在回到数组了。

不过我就考虑字符串行不行的。

有一个比较特殊的字符串。
"a\0b\0d\0"

这个字符串我想让他回到字符串的数组去。
就是
"a\0"
"b\0"
"c\0"

不拷贝内存行不,我在考虑。
c和c++在这个问题上又有何区别
...全文
273 27 打赏 收藏 转发到动态 举报
写回复
用AI写文章
27 条回复
切换为时间正序
请发表友善的回复…
发表回复
lm_whales 2013-04-28
  • 打赏
  • 举报
回复
引用 12 楼 tyh_123 的回复:
[quote=引用 5 楼 lm_whales 的回复:] 数组不存在什么退化问题,数组名就是个指针而已,能过获取数组的大小是编译器的魔法!! 不是C,C++语言里数组定义的样子。 C 的编译器魔法,大概只有 sizeof()运算符和强制转换,与短路求值吧! 其他都是定义以后就确定了的。强制转换好像不算编译器魔法,似乎类型才是。 数据本身是没有类型的,人们使用数据才会有类型, 于是编译器,在没有类型的数据上,施加了类型魔……
请学好c c++在出来随便回复人家的帖子,谢谢![/quote] C,C++的数组不存在退化问题, 只有看到数组实际定义的地方,才能够获取数组的大小; 作为参数传递时和作为引用声明时,是没有办法获取数组大小的。 C的数组只是在汇编语言的基础上增加了类型信息, 所以数组大小的信息,是附赠的,地址信息才是本质的信息。 所以数组名就是指针。 你这个问题,只需要一个一维数组,就可以解决,是你想的太多了。 另外,根据需要,也可以不用"\0" char a[]="abcdefg\0reeiouri\0"; 至于怎么处理是个策略问题,看你如何选择了。 int countstr(char *a) { int len=0;//串长度 int count=0;//串的个数 char *p=a; do{ while(*p){c++; } count++; }while(c); return count; }
  • 打赏
  • 举报
回复
引用 24 楼 hanzhaoshuai 的回复:
C/C++ code?1234567891011121314//这个意思??函数定义时就定义成数组指针void arr(char (*p)[N],m){ int i=0; for (;i<m;i++) //... }void main{ //.... char arry[5][N]; arr(arry,5);} ……
no
  • 打赏
  • 举报
回复
引用 23 楼 zhao4zhong1 的回复:
引用 22 楼 tyh_123 的回复:引用 20 楼 zhao4zhong1 的回复:引用 18 楼 tyh_123 的回复:引用 17 楼 zhao4zhong1 的回复:电脑内存只是一个一维二进制字节数组及其对应的二进制地址; 人脑才将电脑内存中的这个一维二进制字节数组及其对应的二进制地址的某些部分看成是整数、有符号数/无符号数、浮点数、复数、英文字母、阿拉伯数字……
感谢赵老师指点,茅塞顿开
赵4老师 2013-03-21
  • 打赏
  • 举报
回复
电脑内存只是一个一维二进制字节数组及其对应的二进制地址; 人脑才将电脑内存中的这个一维二进制字节数组及其对应的二进制地址的某些部分看成是整数、有符号数/无符号数、浮点数、复数、英文字母、阿拉伯数字、中文/韩文/法文……字符/字符串、函数、函数参数、堆、栈、数组、指针、数组指针、指针数组、数组的数组、指针的指针、二维数组、字符点阵、字符笔画的坐标、黑白二值图片、灰度图片、彩色图片、录音、视频、指纹信息、身份证信息……
ForestDB 2013-03-21
  • 打赏
  • 举报
回复
C/C++都没有多维数组,多维数组只是一维数组的递归定义。 另外如果声称是string(因为用strlen),但是又没有正常的结尾'\0',那我想问玩谁呢? C语言的哲学是,它假定程序员知道自己在做什么,即不SB。 就原始的帖子的需求来看,如果没有别的附件条件,可以这样:

# include <stdio.h>

int main(void)
{
    char * p = "a\0b\0c\0\0\0";
    char (*a)[2] = (char(*)[2])p;
    int i;

    for (i = 0; *a[i] != 0; i++)
    {
        printf("%s\n", a[i]);
    }

    return 0;
}
这有两个限制,每个子串包括结尾0必须等宽,同时,最尾部必须有个空串,以便能知道“数组”的结尾。
兆帅 2013-03-21
  • 打赏
  • 举报
回复

//这个意思??函数定义时就定义成数组指针
void arr(char (*p)[N],m)
{
    int i=0;
    for (;i<m;i++)
        //...

}
void main
{
    //....
    char arry[5][N];
    arr(arry,5);
}
  • 打赏
  • 举报
回复
引用 13 楼 ForestDB 的回复:
如果是C编程,那么 void foo(int * array, int array_lenth); 这样是最佳实践,可以看广泛的API,都是这样处理数组的。 如果是C++,那么有更多更好的选择,比如 void foo(vector<int> & array); 不必在这个上面纠结。
另外TCHAR版本的strlen也不好用,我也未必会放入 _T('\0')进去
  • 打赏
  • 举报
回复
引用 13 楼 ForestDB 的回复:
如果是C编程,那么 void foo(int * array, int array_lenth); 这样是最佳实践,可以看广泛的API,都是这样处理数组的。 如果是C++,那么有更多更好的选择,比如 void foo(vector<int> & array); 不必在这个上面纠结。
哥,我用是的字符串 的 数组。 不是简单一唯的。2唯的。。。。。。。。
ForestDB 2013-03-21
  • 打赏
  • 举报
回复
如果是C编程,那么 void foo(int * array, int array_lenth); 这样是最佳实践,可以看广泛的API,都是这样处理数组的。 如果是C++,那么有更多更好的选择,比如 void foo(vector<int> & array); 不必在这个上面纠结。
  • 打赏
  • 举报
回复
引用 5 楼 lm_whales 的回复:
数组不存在什么退化问题,数组名就是个指针而已,能过获取数组的大小是编译器的魔法!! 不是C,C++语言里数组定义的样子。 C 的编译器魔法,大概只有 sizeof()运算符和强制转换,与短路求值吧! 其他都是定义以后就确定了的。强制转换好像不算编译器魔法,似乎类型才是。 数据本身是没有类型的,人们使用数据才会有类型, 于是编译器,在没有类型的数据上,施加了类型魔……
请学好c c++在出来随便回复人家的帖子,谢谢!
  • 打赏
  • 举报
回复
引用 9 楼 ForestDB 的回复:
从某种意义上来说,数组和指针没什么实质的区别。
区别是没有,但是如果数组被退化成指针,然后指针再回到数组的话,那会方便很多啊。 我是为了这个才打算把它弄回数组去的
  • 打赏
  • 举报
回复
引用 7 楼 CKnightx 的回复:
引用 6 楼 lin5161678 的回复:引用 5 楼 lm_whales 的回复:数组不存在什么退化问题,数组名就是个指针而已,能过获取数组的大小是编译器的魔法!! 不是C,C++语言里数组定义的样子。 C 的编译器魔法,大概只有 sizeof()运算符和强制转换,与短路求值吧! 其他都是定义以后就确定了的。强制转换好像不算编译器魔法,似乎类型才是。 数据本身……
赶脚,讨论数组名是不是指针就太没意义了。 实际上数组名也可以当作指针来用,只不过狭义了。 回到正题吧
赵4老师 2013-03-21
  • 打赏
  • 举报
回复
引用 22 楼 tyh_123 的回复:
引用 20 楼 zhao4zhong1 的回复:引用 18 楼 tyh_123 的回复:引用 17 楼 zhao4zhong1 的回复:电脑内存只是一个一维二进制字节数组及其对应的二进制地址; 人脑才将电脑内存中的这个一维二进制字节数组及其对应的二进制地址的某些部分看成是整数、有符号数/无符号数、浮点数、复数、英文字母、阿拉伯数字、中文/韩文/法文……字符/字符串、函数……
// "abc\0","bcde\0" -> 这样的2个连续字符串,传到某个函数里面以后,想简化成
//
// *(a[2])
// a[0] -> 直接访问abc\0
// a[1] -> 直接访问bcde\0
//
// 或者
//
// "abc","bcde" -> 这样的2个连续字符数组,传到某个函数里面以后,想简化成
//
// *(a[2])
// a[0] -> 直接访问abc
// a[1] -> 直接访问bcde
#include <stdio.h>
#include <string.h>
char s1[]="1abc\0001bcde";
char *s2[2]={"2abc","2bcde"};

char s3[2][6] = {"3abc", "3bcde"};

char p1[5] = {'4', 'a', 'b', 'c', 0};
char p2[6] = {'4', 'b', 'c', 'd', 'e', 0};

char *s4[2]={p1,p2};

void func1(void *p) {
    char *a[2];

    a[0]=(char *)p;
    a[1]=(char *)p+strlen((char *)p)+1;

    printf("func1\n");
    printf("a[0]==[%s],a[1]==[%s]\n",a[0],a[1]);
}
void func2(void *p) {
    char *a[2];

    a[0]=((char **)p)[0];
    a[1]=((char **)p)[1];

    printf("func2\n");
    printf("a[0]==[%s],a[1]==[%s]\n",a[0],a[1]);
}
void func3(void *p) {
    char *a[2];

    a[0]=(char *)p;
    a[1]=(char *)p+6;

    printf("func3\n");
    printf("a[0]==[%s],a[1]==[%s]\n",a[0],a[1]);
}
int main() {
    func1(s1);
    func2(s2);
    func3(s3);
    func2(s4);
    return 0;
}
//func1
//a[0]==[1abc],a[1]==[1bcde]
//func2
//a[0]==[2abc],a[1]==[2bcde]
//func3
//a[0]==[3abc],a[1]==[3bcde]
//func2
//a[0]==[4abc],a[1]==[4bcde]
一切“技巧”都来自: VC调试时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化,这样过一遍不就啥都明白了吗。 对VC来说,所谓‘调试时’就是编译连接通过以后,按F10或F11键单步执行一步以后的时候,或者在某行按F9设了断点后按F5执行停在该断点处的时候。 (Turbo C或Borland C用Turbo Debugger调试,Linux或Unix下用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。) 想要从本质上理解C指针,必须学习汇编以及C和汇编的对应关系。 从汇编的角度理解和学习C语言的指针,原本看似复杂的东西就会变得非常简单! 指针即地址。“地址又是啥?”“只能从汇编语言和计算机组成原理的角度去解释了。” 但我又不得不承认: 有那么些人喜欢或者适合用“先具体再抽象”的方法学习和理解复杂事物; 而另一些人喜欢或者适合用“先抽象再具体”的方法学习和理解复杂事物。 而我本人属前者。 这辈子不看内存地址和内存值;只画链表、指针示意图,画堆栈示意图,画各种示意图,甚至自己没画过而只看过书上的图……能从本质上理解指针、理解函数参数传递吗?本人深表怀疑! 这辈子不种麦不收麦不将麦粒拿去磨面;只吃馒头、吃面条、吃面包、……甚至从没看过别人怎么蒸馒头,压面条,烤面包,……能从本质上理解面粉、理解面食吗?本人深表怀疑!! 提醒: “学习用汇编语言写程序” 和 “VC调试(TC或BC用TD调试)时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化,这样过一遍不就啥都明白了吗。 (Linux或Unix下可以在用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。) 想要从本质上理解C指针,必须学习C和汇编的对应关系。” 不是一回事! 不要迷信书、考题、老师、回帖; 要迷信CPU、编译器、调试器、运行结果。 并请结合“盲人摸太阳”和“驾船出海时一定只带一个指南针。”加以理解。 任何理论、权威、传说、真理、标准、解释、想象、知识……都比不上摆在眼前的事实! 有人说一套做一套,你相信他说的还是相信他做的? 其实严格来说这个世界上古往今来所有人都是说一套做一套,不是吗? 不要写连自己也预测不了结果的代码!
  • 打赏
  • 举报
回复
引用 20 楼 zhao4zhong1 的回复:
引用 18 楼 tyh_123 的回复:引用 17 楼 zhao4zhong1 的回复:电脑内存只是一个一维二进制字节数组及其对应的二进制地址; 人脑才将电脑内存中的这个一维二进制字节数组及其对应的二进制地址的某些部分看成是整数、有符号数/无符号数、浮点数、复数、英文字母、阿拉伯数字、中文/韩文/法文……字符/字符串、函数、函数参数、堆、栈、数组、指针、数组指针、指针数……
不过你的fun2,好像赶脚。有点哪里怪怪的。 char *s2[2]={"abc","bcde"}; 这个应该是指向了2个常量上面了吧。 其实这个我是这么个意思 char s2[2][4] = {"abc\0", "bcde"}; 或者 char *s2[2]; char p1[3] = {'a', 'b', 'c'}; char p2[4] = {'b', 'c', 'd', 'e'}; s2[0] = p1; s2[1] = p2; 不过貌似不纠结了,赵老师有兴趣就回复,没兴趣就算了。 我也只打算问问技巧性的玩意。
  • 打赏
  • 举报
回复
引用 20 楼 zhao4zhong1 的回复:
引用 18 楼 tyh_123 的回复:引用 17 楼 zhao4zhong1 的回复:电脑内存只是一个一维二进制字节数组及其对应的二进制地址; 人脑才将电脑内存中的这个一维二进制字节数组及其对应的二进制地址的某些部分看成是整数、有符号数/无符号数、浮点数、复数、英文字母、阿拉伯数字、中文/韩文/法文……字符/字符串、函数、函数参数、堆、栈、数组、指针、数组指针、指针数……
赵老师高!不过我发帖之初是纠结在不用strlen或者tchar版本的strlen上。
赵4老师 2013-03-21
  • 打赏
  • 举报
回复
引用 18 楼 tyh_123 的回复:
引用 17 楼 zhao4zhong1 的回复:电脑内存只是一个一维二进制字节数组及其对应的二进制地址; 人脑才将电脑内存中的这个一维二进制字节数组及其对应的二进制地址的某些部分看成是整数、有符号数/无符号数、浮点数、复数、英文字母、阿拉伯数字、中文/韩文/法文……字符/字符串、函数、函数参数、堆、栈、数组、指针、数组指针、指针数组、数组的数组、指针的指针、二维数组、字…… 赵老师。我不是那个意思。。。 我想把访问 字符串的 数组 或者 字符(串) 的数组 工作搞简单一点。 我意思是这样的。 "abc\0","bcde\0" -> 这样的2个连续字符串,传到某个函数里面以后,想简化成 *(a[2]) a[0] -> 直接访问abc\0 a[1] -> 直接访问bcde\0 或者 "abc","bcde" -> 这样的2个连续字符数组,传到某个函数里面以后,想简化成 *(a[2]) a[0] -> 直接访问abc a[1] -> 直接访问bcde
// "abc\0","bcde\0" -> 这样的2个连续字符串,传到某个函数里面以后,想简化成
//
// *(a[2])
// a[0] -> 直接访问abc\0
// a[1] -> 直接访问bcde\0
//
// 或者
//
// "abc","bcde" -> 这样的2个连续字符数组,传到某个函数里面以后,想简化成
//
// *(a[2])
// a[0] -> 直接访问abc
// a[1] -> 直接访问bcde
#include <stdio.h>
#include <string.h>
char s1[]="abc\0bcde";
char *s2[2]={"abc","bcde"};
void func1(void *p) {
    char *a[2];

    a[0]=(char *)p;
    a[1]=(char *)p+strlen((char *)p)+1;

    printf("func1\n");
    printf("a[0]==[%s],a[1]==[%s]\n",a[0],a[1]);
}
void func2(void *p) {
    char *a[2];

    a[0]=((char **)p)[0];
    a[1]=((char **)p)[1];

    printf("func2\n");
    printf("a[0]==[%s],a[1]==[%s]\n",a[0],a[1]);
}
int main() {
    func1(s1);
    func2(s2);
    return 0;
}
//func1
//a[0]==[abc],a[1]==[bcde]
//func2
//a[0]==[abc],a[1]==[bcde]
  • 打赏
  • 举报
回复
引用 16 楼 ForestDB 的回复:
C/C++都没有多维数组,多维数组只是一维数组的递归定义。 另外如果声称是string(因为用strlen),但是又没有正常的结尾'\0',那我想问玩谁呢? C语言的哲学是,它假定程序员知道自己在做什么,即不SB。 就原始的帖子的需求来看,如果没有别的附件条件,可以这样: C/C++ code?123456789101112131415# includ……
mark了,学习了。这也是一个办法。
  • 打赏
  • 举报
回复
引用 17 楼 zhao4zhong1 的回复:
电脑内存只是一个一维二进制字节数组及其对应的二进制地址; 人脑才将电脑内存中的这个一维二进制字节数组及其对应的二进制地址的某些部分看成是整数、有符号数/无符号数、浮点数、复数、英文字母、阿拉伯数字、中文/韩文/法文……字符/字符串、函数、函数参数、堆、栈、数组、指针、数组指针、指针数组、数组的数组、指针的指针、二维数组、字符点阵、字符笔画的坐标、黑白二值图片、灰度图片、……
赵老师。我不是那个意思。。。 我想把访问 字符串的 数组 或者 字符(串) 的数组 工作搞简单一点。 我意思是这样的。 "abc\0","bcde\0" -> 这样的2个连续字符串,传到某个函数里面以后,想简化成 *(a[2]) a[0] -> 直接访问abc\0 a[1] -> 直接访问bcde\0 或者 "abc","bcde" -> 这样的2个连续字符数组,传到某个函数里面以后,想简化成 *(a[2]) a[0] -> 直接访问abc a[1] -> 直接访问bcde
ForestDB 2013-03-15
  • 打赏
  • 举报
回复
从某种意义上来说,数组和指针没什么实质的区别。
zhong386615716 2013-03-15
  • 打赏
  • 举报
回复
C语言是面向过程的,C++是面向对象的。C语言中的精华是指针,而C++中是类。从C和C++发展起来的C# 都没有指针了。
加载更多回复(7)

64,654

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧