简体   繁体   English

关于C中char和int指针的一些疑问

[英]A few doubts about char and int pointers in C

I have a question about pointers in C. 我对C中的指针有疑问。

[1] char *somestring = "somestring"

and

[2] int *someint = 45

why [1] works and [2] not? 为什么[1]有效,[2]没有?

and why do we 为什么我们

printf("%s",str1);

and not 并不是

printf("%s",*str1);

?

In C a literal string is basically a (read-only) array of characters, so char* (yes, it should be const char*, but that's lost to history). 在C中,一个文字字符串基本上是一个(只读)字符数组,所以char *(是的,它应该是const char *,但是它会丢失到历史记录中)。 A literal int is not an array or pointer, so making a pointer to it is nonsensical. 文字int不是数组或指针,因此制作指向它的指针是没有意义的。 The types just don't match. 类型不匹配。

[2] int *someint = 45

doesn't work because you can't cast int to int * without an explicit cast. 不起作用,因为如果没有显式强制转换,您无法将int转换为int *。

Edit: Actually, I just tried to compile an example code and it compiles with GCC 4.7 under linux, but it prints out an warning message. 编辑:实际上,我只是尝试编译一个示例代码,它在Linux下编译GCC 4.7,但它打印出一条警告消息。

45 is considered as an int. 45被认为是int。

[2] int *someint = (int *) 45

regarding printf , %s means, substitute %s with a char * array, and stop when you reach '\\0' 关于printf%s表示用%s char *数组替换%s ,到达'\\0'时停止

In char *somestring = "somestring" , "somestring" is list/array of characters. char *somestring = "somestring" ,“somestring”是列表/字符数组。

while in int *someint = 45 45 is just one integer not list/array of ints. 而在int *someint = 45 45只是一个整数而不是整数列表/数组。 It is equivalent to char *somestring = 'a' which is not valid. 它相当于char *somestring = 'a'无效。

When you declare a string literal eg "somestring" the compiler knows about this at compile time and puts it into a separate section of memory in your program. 当您声明一个字符串文字,例如"somestring" ,编译器会在编译时知道这一点并将其放入程序的单独内存部分。 The compiler then assigns the memory address of this location to your string pointer. 然后,编译器将此位置的内存地址分配给字符串指针。

The alternative would be to store the characters for a string on the stack: 另一种方法是将字符串中的字符存储在堆栈中:

char someString[] = { 's', 'o', 'm', 'e', ' ', 's', 't', 'r', 'i', 'n', 'g', 0 };

Because an integer is smaller than a string (and fits into a memory location) it's generally just delcared on the stack. 因为整数小于字符串(并且适合内存位置),所以通常只是在堆栈上进行delcared。

int someInt = 45;
int *someint = 45;

is the same as saying: 和说:

int *someint;
someint = 45;

This will compile with the warning: 这将编译警告:

initialization makes pointer from integer without a cast

And will compile without warning if you cast it: someint = (int *)45; 并且如果你someint = (int *)45;它将在没有警告的情况下编译: someint = (int *)45; .

This is because, you're basically saying that the "value" of someint is stored at address 45, or 0x2d , which is obviously not the case as of the declaration. 这是因为,你基本上是说someint的“值”存储在地址45或0x2d ,这显然不是声明​​的情况。

You can now add a value by dereferencing: *someint = someval; 您现在可以通过解除引用来添加值: *someint = someval; . So now someval will be stored at the address you specified earlier (though this may not work, depending on whatever the OS has stored there already). 因此,现在someval将存储在您之前指定的地址中(尽管这可能不起作用,具体取决于操作系统已存储的位置)。

I hope this clears things up. 我希望这可以解决问题。

Starting with the first part of your question, let's see what happens when you use statement: 从问题的第一部分开始,让我们看看使用语句时会发生什么:

char *somestring = "somestring";

Here,you declare a character pointer somestring , the string somestring is stored at some address in the memory and that address is allocated to the pointer somestring (Believe me, it's confusing to use the same name for the pointer and the contents of the string it is pointed to, as you have done!!) 在这里,你声明一个character pointer somestring ,字符串somestring存储在内存中的某个地址,并且该地址被分配给指针somestring (相信我,令人困惑的是使用相同的名称作为指针和字符串的内容吧指出,正如你所做的那样!)

Now you can refer to that string using this pointer somestring . 现在,您可以使用此指针somestring引用该字符串。

Now see, how it is different in the following statement, which will produce errors: 现在看看,以下语句中的不同之处将产生错误:

int *someint = 45

Here you are declaring an integer pointer someint (of type int* ) but assigning an integer value (of type int ) to it.Not only is there a type mismatch, but it can produce unpredictable behavior as you just have no idea what is already at address 45.I suppose this is what you need: 在这里,你声明一个整数指针someint (类型为int* ),但为它指定一个整数值(类型为int )。不仅存在type不匹配,但它会产生不可预测的行为,因为你只是不知道已经是什么在地址45.我想这就是你需要的:

 int num=45,*someint=#

Here the & address of operator assigns the address of the variable num to the pointer, and you can dereference it using the * operator as following: 在这里, &运营商的地址赋给变量的地址num指针,你可以取消对它的引用使用*操作如下:

  printf("The value pointed by the pointer is ",*someint);

Note how * before someint carries a different meaning in the declaration statement and as an argument to printf() . 注意在someint之前*在声明语句中具有不同的含义以及作为printf()的参数。

Coming to the second part of your question, why we use str1 in printf() instead of *str1 , well, str1 signifies the base address of the string ,which is nothing but the address of the first character in the array. 来到你的问题,为什么我们使用的第二部分str1printf()而不是*str1 ,好了, str1表示字符串,这不过是数组中的第一个字符的地址的基址 So going by what I told you about the * operator, *str1 means the character stored at the base address of the array,ie, the first character of the array.Run the following code and it will be clear: 所以按照我告诉你的*运算符, *str1表示存储在数组基址的字符,即数组的第一个字符。运行以下代码,它将很清楚:

#include<stdio.h>

int main(void)
{   
     char str1[10]="Davies";

     printf("str1 is : %s \n but *str1 is : %c",str1,*str1);
}

Output str1 is : Davies 输出 str1 is : Davies

        but *str1 is : D

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM