C:关于使用指针的困惑

时间:2013-12-31 12:16:39

标签: c pointers

我正在阅读C编程书。我正在阅读并练习使用带指针的Xcode。

我想知道为什么这行代码只打印文字字符数组H的第一个字符string而不是完整字符串"Hello"

char *myCharPointer = "Hello";

printf("The value of myCharPointer is %c \n \n", *myCharPointer);

我的印象是字符串文字返回该数组中第一个字符的地址,然后,我认为会自动按顺序打印字符的重置。这个思考过程背后的原因是前面的一个例子,它演示了一个类似的string被传递给函数中的char指针,然后该char指针的地址被传递给{{ 1}}用于读取所有字符的函数。我也尝试将格式说明符更改为strcpy(),但程序崩溃了。

我也有点困惑为什么:

%s

而不是:

int myIntArray[10];
int *myIntArrayPointer;

myIntArrayPointer = myIntArray;

我知道int myIntArray[10]; int *myIntArrayPointer; myIntArrayPointer = &myIntArray; 尚未定义,但仅仅是一个例子

7 个答案:

答案 0 :(得分:1)

  

我想知道为什么这行代码只打印文字字符数组H的第一个字符string而不是完整字符串"Hello"

char *myCharPointer = "Hello";

myCharPointer是指向字符串文字Hello的第一个字符的指针,即H。在*中使用*myCharPointer运算符购买您取消引用指针myCharPointer,该指针将提供存储在myCharPointer指向的位置H的值。这就是你得到H的原因。

  

我也尝试将格式说明符更改为%s,但程序崩溃了。

*myCharPointer属于char类型,您需要%c说明符才能打印char。要打印字符串文字,请使用%s说明符

 printf("The value of myCharPointer is %s \n \n", myCharPointer);   

要打印地址的值,请使用%p说明符

 printf("The value of myCharPointer is %p \n \n", (void *)myCharPointer);  

摘录

int myIntArray[10];
int *myIntArrayPointer;

myIntArrayPointer = myIntArray;  

有效,因为myIntArrayPointerpointer to int类型。数组名称衰减到指针(并非总是),因此myIntArray也是指向int类型的指针,这就是myIntArrayPointer = myIntArray;有效的原因。

int myIntArray[10];
int *myIntArrayPointer;

myIntArrayPointer = &myIntArray;    

&myIntArray的类型为int (*)[10],即指向10个整数数组的指针。如上所述,myIntArrayPointer的类型为int *,因此赋值无效。

  

我也尝试将格式说明符更改为%s,但程序崩溃了。

答案 1 :(得分:1)

首先,它会打印一个字符,因为您告诉 printf打印单个字符(使用"%c"格式说明符)。其次,变量myCharPointer确实指向字符串文字"Hello"的开头(更具体地说,它指向字符'H'在内存中的位置),以及何时使用取消引用operator *你得到指针指向的位置的,在这种情况下是一个字符。

第三,字符串文字实际上是常量和只读,因此您应该将myCharPointer声明为指向常量数据的指针,或者将其设为数组。所以要么

const char *myCharPointer = "Hello";

char myCharPointer[] = "Hello";

答案 2 :(得分:1)

当您为指针指定字符串时,指针将指向第一个字符 我认为这个链接可能有用C Strings

对于你的下一个问题,数组有点像指针myIntArray是指向数组的第一个元素的地址,你不应该使用'&'用它myIntArray [i]就像你指向数组的第i个元素

答案 3 :(得分:1)

在第一种情况下,您使用%c限定符,该限定符告诉printf写一个由char指向的myCharPointer。 它实际上等于写:

char *myCharPointer = "Hello";
printf("The value of myCharPointer is %c \n \n", myCharPointer[0]);

对不起,我无法向你展示一个关于myCharPointer在RAM中的样子的方案。

myIntArrayPointer = myIntArray; 

是正确的,因为myIntArray是一个数组,但是不要忘记该数组只是C中的语法糖。数组基本上是指向数组本身第一个元素的指针。 之间没有区别:

*(myIntArray + 2) = 5;
myIntArray[2] = 5;

答案 4 :(得分:1)

要打印字符串,请使用%s转换说明符,并且不要取消引用指针:

printf("The value of myCharPointer is %s \n \n", myCharPointer);

这告诉printf打印从myCharPointer给出的地址开始的字符,直到它看到0终结符。

  

我的印象是字符串文字返回该数组中第一个字符的地址

或多或少正确;除非它是sizeof或一元&运算符的操作数,或者是一个字符串文字用于初始化声明中的另一个数组,表达式为“N元素数组{{1 “将被转换(”衰减“)到”指向T的指针“类型的表达式,表达式的值将是数组中第一个元素的地址。

字符串文字T的类型为“6个元素的"Hello"数组”(5个字符加上0个终结符)。在声明中

char

它不是char *myCharPointer = "Hello"; 或一元sizeof运算符的操作数,也不是用来初始化&数组,所以上面规则适用;它被转换为“指向char的指针”的表达式,并且计算为第一个字符的地址。

我也有点困惑为什么这个:
char

回到上面的规则;由于表达式 int myIntArray[10]; int *myIntArrayPointer; myIntArrayPointer = myIntArray; 不是myIntArray或一元sizeof运算符的操作数,因此它将转换为“指向&”的类型的表达式。

并不是:
int

这一次, int myIntArray[10]; int *myIntArrayPointer; myIntArrayPointer = &myIntArray; 是一元myIntArray运算符的操作数,因此上述规则不再适用;表达式&的类型是“指向 10元素数组的指针 &myIntArray”(int),不是 {{ 1}}。这些类型不是兼容,因此您无法将其分配给另一个。

请注意int (*)[10]int *是相同的;数组的地址与数组的第一个元素的地址相同。它只是不同的类型,但类型很重要。

答案 5 :(得分:0)

第一部分是打印单个字符而不是整个字符串,因为您指定了%c,这表示应该打印单个字符。 要打印整个字符串,请使用

char *myCharPointer = "Hello";

printf("The value of myCharPointer is %c \n \n", myCharPointer);

(只需删除myCharPointer的星号)

至于第二部分, myIntArray 是int数组的名称,它还指向到该int数组的第一个元素。所以你应该选择

myIntArrayPointer = myIntArray;

答案 6 :(得分:0)

  

我想知道为什么这行代码只打印文字字符数组字符串的第一个字符H而不是完整字符串“Hello”

首先,指针char*被定义为指向一个字符。对于您的示例,H中的Hello。使用字符串,您将在连续内存中定义数据。例如,

char  [H][e][l][l][o][\0]
index [0][1][2][3][4][5]

指针仅用作迭代内存中每个字符的方法。这意味着myCharPointer = H(0)++myCharPointer = e(1)

打印字符串时,您将执行以下操作:

printf("The value of myCharPointer is %s \n \n", myCharPointer);

  

我知道myIntArray尚未定义,但它只是一个例子

整数指针和整数数组在赋值的上下文中基本相同。指针可以遍历内存块,因此您的直接赋值myIntArrayPointer = myIntArray是正确的。

作为旁注:

如果您有常规字符char myChar = 'a';,则可以使用&在内存中获取其地址。例如,char* myCharPointer = &myChar; - > myCharPointer现在指向myChar。要获取地址的值,只需使用解除引用运算符*myCharPointer,即'a'