| #include<stdio.h> void main() {char *a[2]; int i; for(i=0;i<2;i++) scanf(“%s”,a+i); //a不是a[i]的地址吗?这样输入的值不是给了a[i]吗?而a[i]应该是存地址才对呀 for(i=0;i<2;i++) printf(“%s\n”,a+i);//怎么输出不是写成*a[i]? } 求高手为我解答上面的问题! 顺便给我说一下%s的原理 | |
| #1 | 
把%s的内容赋给a+i,然后以%s输出a+i,肯定还是原字符串啊,输出格式改成%x或%d才会输出地址*a[i] | 
| #2 | 
http://baike.baidu.com/view/2072881.htm | 
| #3 | 
#include<stdio.h>
void main()
{
	char *a[2] ;
	a[0] = new char[10];
	a[1] = new char[10];
	int i;
	for(i=0;i<2;i++)
	{
		scanf("%s",a[i]);    //对于字符串数组或字符串指针变量,由于数组名和指针变量名本身就是地址,
	}								//因此使用scanf()函数时,不需要在它们前面加上"&"操作符。
	for(i=0;i<2;i++)
	{
		printf("%s\n",a[i]);//字符串都要以地址形式来打印的 配合%s使用
	}
	for ( i=0;i<2;++i)
	{
		delete [] a[i];
	}
} | 
| #4 | 
//a不是a[i]的地址吗?这样输入的值不是给了a[i]吗?而a[i]应该是存地址才对呀
 参数要求传入的是地址。 | 
| #5 | 回复3楼: 无视我的 new和delete吧, C里木有…. | 
| #6 | #include<stdio.h>
 void main()
 {char *a[2];
 int i;
 for(i=0;i<2;i++)
 scanf("%s",a+i);    //a不是a[i]的地址吗?这样输入的值不是给了a[i]吗?而a[i]应该是存地址才对呀
//REP: 输入是给了a[i], 比如输入为"1234ACD0",所以a[i]的值就为"1234ACD0", 而这个值呢,是一个字符指针,也就是一个地址
 for(i=0;i<2;i++)
 printf("%s\n",a+i);//怎么输出不是写成*a[i]?
//REP: 你要输出a[i]的值,也就是1234ACD0这个值,若写成*a[i],则输出的是124ACD0这个地址里面的值
 }
  | 
| #7 | 回复6楼: 六楼的兄弟,你是说要输入一个地址吧。可是我需要的是要输入一个字符串啊 | 
| #85分 | 
是输入字符串啊,只不过这个字符串是地址!
 如果想输入真正的字符串的话: 需要先对char *a[2];初始化,for example: a[1] = malloc(); 然后于对a[1]输入字符串 | 
| #9 | 回复8楼: 只是现在不用初始化,也能执行呀 | 
| #10 | 
所以你输入的就是一个地址
 | 
| #11 | 回复10楼: 我输入了:yy ty 它也可以的哦 这个程序是能执行的,我只是有些不理解,输入和输出那里字符指针数组的写法 | 
| #125分 | 
你定义的是一个指针数组,并没有给这个数组里面的每个指针分配空间
 给你的代码修改了一下 #include<stdio.h>
#include <stdlib.h>
#define N 20
void main()
{
	char *a[2];
	int i;
	for(i=0;i<2;i++)
		a[i]=(char *)malloc(sizeof(char)*N);
	for(i=0;i<2;i++)
		scanf("%s",a[i]);    //a你定义的不是数组名,是一个指针数组,也就是指针,但加i只是该行字符串往后移动i位
	for(i=0;i<2;i++)
		printf("%s\n",a[i]);//怎么输出不是写成*a[i]?
	for(i=0;i<2;i++)
		free(a[i]);
} | 
| #135分 | 
不知道楼主想做什么,如果你要是使用字符指针数组来输入字符串的话可以这样用:
 #include <stdio.h>
#include <stdlib.h>
void main()
{
   char *a[2];
   int i;
   for(i=0;i<2; i++)
   {
      *(a + i) = (char *)malloc(10*sizeof(char));
      scanf("%s",*(a+i));    //a不是a[i]的地址吗?这样输入的值不是给了a[i]吗?而a[i]应该是存地址才对呀
   }
   for(i=0;i<2;i++)
   {
      printf("%s\n",*(a+i));//怎么输出不是写成*a[i]?
      free(*(a + i));
   }
}scanf("%s",a+i);    //a不是a[i]的地址吗?这样输入的值不是给了a[i]吗?而a[i]应该是存地址才对呀scanf函数的功能是将要输入的数据存放到你指定的已经分配的地址中(也就是指针中)而a + i还是指针类型么,不是的,它是指针的指针。有没有可以直接进行控制指针的格式呢,好像目前还没有,所以才会出现编译错误。但是为了还能进行使用,所以我们首先解引用回到指针这个层面上来就比较容易一些了。 | 
| #14 | 回复12楼: 对,我的这个程序是没问题的。可以执行。可不明白为什么能执行。 | 
| #15 | 回复13楼: 我的这个程序是没问题的。可以执行。可不明白为什么能执行。 | 
| #165分 | 回复14楼: 因为数组的接线时程序员自己控制,编译器是完全相信程序员的 所以就很容易出现问题 因为你这个指针都没有初始化,就直接进行操作了,所以很危险的操作了 | 
| #17 | 
引用
 
 数组指针是要分配足够内存的。 //a不是a[i]的地址吗?这样输入的值不是给了a[i]吗?而a[i]应该是存地址才对呀 //怎么输出不是写成*a[i]? 你的理解是对的,但 字符串处理时特殊一点。有关C-style字符串。 | 
| #18 | 回复17楼: 可以的详细给我说一下吗 | 
| #19 | 
char *str = “mm”;
 printf(“%s”,str);//输出mm。 printf(“%d”,str);//输出str[0]的地址。 编译器支持上面的语法。c风格的字符串的指针比其他的略特殊了。 | 
| #20 | 
指针太重要了  | 
| #21 | 
学习学习,好像确实指针的指针没法输出。 | 
| #2240分 | 
printf里面的%和变量的一一对应关系
 scanf里面的%和变量以及变量前加不加&的一一对应关系 是C代码中非常容易出错的地方,而且通常编译还不出错。 所以在编译源代码之前值得专门仔细检查一遍甚至多遍。 VC调试时按Alt+8、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+6和Alt+5,打开汇编窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应内存和寄存器变化,这样过一遍不就啥都明白了吗。 (Linux或Unix下可以在用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。) 想要从本质上理解C指针,必须学习C和汇编的对应关系。” 不是一回事! 不要迷信书、考题、老师、回帖; 要迷信CPU、编译器、调试器、运行结果。 并请结合“盲人摸太阳”和“驾船出海时一定只带一个指南针。”加以理解。 任何理论、权威、传说、真理、标准、解释、想象、知识……都比不上摆在眼前的事实! 有人说一套做一套,你相信他说的还是相信他做的? 其实严格来说这个世界上古往今来所有人都是说一套做一套,不是吗? 不要写连自己也预测不了结果的代码! 电脑内存只是一个一维二进制字节数组及其对应的二进制地址; 人脑才将电脑内存中的这个一维二进制字节数组及其对应的二进制地址的某些部分看成是函数、函数参数、堆、栈、数组、指针、数组指针、指针数组、数组的数组、指针的指针、二维数组、…… | 
| #23 | 
   谢谢各位,以上问题经过一次次的测试,发现当输入字节数超过8个字节时,以上写法也会出错。因为VC中指针分配四个字节,所以上写法输入超过8个字节时,就会溢出。结合以上各位的说法,也就理解为VC编译器的一种特性,就是你给a[i]的输入不是地址它也能执行。正确方法就是先给每个指针数组分配空间。 | 
| #24 | 回复22楼: 谢谢您的回答,谢谢您介绍的方法 | 
| #25 | 
#include <stdio.h>
 int main(void) { char ar[20], scanf(“%s”,ar); printf(“%s”,ar); return 0; } 为啥不用循环每次输入下次都会指向下一个地址? | 
| #26 | 
这个问题也困惑我好长时间,   printf(“%s\n”,a+i);//怎么输出不是写成*a[i]?  为什么不能写成*a[i],举个例子啊,如果第一次你的输入为”abcdef”,第二次输入”ghijk”  那么a[0]是字符a的地址,而*a[0]则是字符””a””,输出要用printf(“%c”,*a[i]);   *a[1]为g,  但按理来说指针变量必须是用一个地址初始化。但使用printf(“%s”,a+i);确实能输出你刚才输入的两个字符串,这让我开始怀疑这个指针变量中到底存储的是a或者是g的地址,还是abcdef 或者ghijk这两个字符串。 | 
 
                    

