我是指针的新手,我对代码的这一部分感到困惑。我有几个问题:
在第1行中,我不确定双星号的含义。我读到它是另一个指针的指针,但我不完全是那个。
在第4行中,我不知道如何解释语法:
*(*(total_number_of_pages + x) + y)
/* total_number_of_pages
* This stores the total number of pages in each book of each shelf.
* The rows represent the shelves and the columns represent the books.
*/
int** total_number_of_pages; // (Line 1)
int x, y; // (Line 2)
scanf("%d %d", &x, &y); // (Line 3)
printf("%d\n", *(*(total_number_of_pages + x) + y)); // (Line 4)
答案 0 :(得分:3)
实际上*(*(total_number_of_pages + x) + y)
很难“增长”。这是C语言提供另一种表示法的原因:*(E1 + E2)
也可以写成E1[E2]
(或E2[E1]
换成+
换行)。我们可以在您的表达式中应用此规则以获取:*(total_number_of_pages[x] + y)
,然后再次获取:total_number_of_pages[x][y]
。
这更清楚。 total_number_of_pages
是指向类似数组的内存区域底部的指针。 total_number_of_pages[x]
表示此元素的第x
个元素的值。该元素本身就是指向另一个数组的指针,其中[y]
表示第y
个值。
在您的程序中,total_number_of_pages
没有任何值,这意味着在表达式*(*(total_number_of_pages + x) + y)
中使用它会引起未定义的行为。为了使表达式有效,它必须指向至少包含x + 1
个元素的指针数组,并且该数组的[x]
元素必须指向一个int
数组,该数组具有至少y + 1
个元素。
答案 1 :(得分:0)
想象一下,如果您有一排书,并且想知道该行中每本书有多少页。您可以使用存储在连续内存地址中的整数集合。
现在说你有很多书。您可能会使用指向书的每一行的指针的集合,而书的每一行都是存储在连续内存地址中的整数的集合。
由于每行都是一个指针,所以这些行的地址是一个指向指针的指针。因此int**
。
现在,total_number_of_pages
是指向行的第一个指针的指针。要获得第二个指针,您需要添加一个。要进入第x
行,您需要向其中添加x
。如果取消引用该指针,则会获得指向第x
行的第一本书的指针。如果您想要第y
本书,则向其中添加y
。现在,您在第y
行的第x
书中有一个指针,您可以对其进行引用以获取该书中的页数。
如果您对指针不是很熟悉,那么您真的不应该尝试理解这样的代码。
答案 2 :(得分:0)
指针是包含内存地址的变量。要声明指针变量,只需在名称前使用星号声明常规变量。
int *ptr;
我将尝试用一些图形和更少的代码来解释指向您的指针。
#include <iostream>
int main()
{
int num = 5; //Just a regular integer variable.
char hello[] = "Hello World!"; // An array of characters.
int* point_to_num = # // & return's the memory address of a variable.
char* point_to_hello = hello; //Notice that I don't use &. Arrays are already pointers!
//----------Dereferencing Pointers----------//
printf("%d\n", *point_to_num); //This will print 5
//No Dereferencing needed.
printf("%s\n", hello); //This will print "Hello World!"
printf("%s\n", point_to_hello); //This will print "Hello World!" again!
return 0;
}
如果将代码与图像进行比较,则 point_to_num 是包含内存地址3000的第三矩形。当您使用星号取消引用指针时:
printf("%d\n", *point_to_num); //This will print 5
您说的是“带给我内存地址3000中包含的值”
但是在这种情况下:
printf("%s\n", hello); //This will print "Hello World!"
printf("%s\n", point_to_hello); //This will print "Hello World!" again!
字符串是一个字符序列,您必须提供一个指向该序列开头的指针,以便printf打印该字符串,直到找到特殊的null terminate character。
在您的代码中
int** total_number_of_pages;
页面总数未初始化,这意味着我们不能说输出什么。
printf("%d\n", *(*(total_number_of_pages + x) + y)); // (Line 4)