#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char** AllocateShoppingList(int numFoods);
char* AllocateItem();
int DetermineNumberOfCandy(char** list, int numFoods);
int main()
{
char** stringArray;// pointer to pointers
char* words; //pointer to char array
//1. ask the user how many foods are on their list
int foods;
printf("How many foods on the shopping list?\n");
scanf("%d", &foods);
//2. call the AllocateShoppingList function and store the result
stringArray = AllocateShoppingList(foods);
//3. for X times (user's previous input), call the AllocateItem function
// and store the result in the list of pointers (step 2)
for(int i =0;i < foods; i++){
words = AllocateItem();
stringArray[i] = words;}
//strcpy(stringArray[i],words); why not work?
//4. call the DetermineNumberOfCandy function, and print the result
printf("Candy appeared this many times: %d\n",DetermineNumberOfCandy(stringArray, foods));
//5. free up all of the pointers that are held by the shopping list
//6. free up the shopping pointer itself
free(words);
free(stringArray);
}
int DetermineNumberOfCandy(char** list, int numFoods)
{
//0. setup a counter variable
int counter = 0 ;
//1. for each pointer in the shopping list:
//1a. compare the string at the pointer's address to "candy"
for(int i =0; i< numFoods; i++)
if (strcmp(list[i],"candy")==0)
// why you dont have to dereference it
// this concept works with single pointers
// does it work with double or tripple pointers as long as it orignally points to the string?
counter++;
//1b. if it is candy, then tick up the counter variable
//2. return the counter variable
return counter;
}
char** AllocateShoppingList(int numFoods)
{
return calloc(numFoods, sizeof(char*));
//1. allocate memory that can hold X pointers (X = numFoods)
//2. return the memory address holding this pointer to pointers
}
char* AllocateItem()
{
char* wordPtr;
char word[100];
//1. get a word from the user that is max 100 characters
scanf("%s", word);
//2. determine how large the word actually is
wordPtr = calloc(strlen(word)+1,sizeof(char));
strcpy(wordPtr, word);
//3. allocate memory that is just enough to hold the word
return wordPtr;
//4. copy the user's word into the new memory location
//5. return the memory address holding the word
}
在这段代码中,我们必须最后得到一个shopping,然后打印出candy在购物清单中出现的次数。为了做到这一点,我们必须分配足够的内存来保存用户希望在购物清单中出现的单词(字符串)。然后,为每个项目分配足够的内存来存储单词。
这份声明对我来说毫无意义
**char** stringArray; **
根据我的理解,双指针是一个数组,数组中的元素包含一个指向字符串地址的指针。
因此,我认为我们必须像这样声明双指针:
字符串数组[];
像这样的东西,但那是行不通的
所以我想知道如果我们不加括号代码怎么知道它是一个指针数组
我试着用数组声明双指针,但无法让它工作,也不能弄清楚它是否可能。
2条答案
按热度按时间dbf7pr2w1#
指针是指针,数组是数组。然而,当C语言中的数组被用于表达式或作为参数传递给函数时,它会“衰减”为指向数组第一个元素的指针。这反过来又使指针运算和
[]
索引运算符的方便使用成为可能。这也意味着在大多数情况下,指向第一个元素的指针可以用来代替数组,如果我们有一个指针数组
char* arr[n];
,那么char**
可以用来指向第一个元素,然后从那里指向数组的其余部分。所以如果你想写一个像
int DetermineNumberOfCandy(int numFoods, char* list[numFoods]);
这样的函数,这是很好的和有效的C语言,但是list
无论如何都会“衰减”成一个指向第一个元素的指针,所以它100%等价于int DetermineNumberOfCandy(int numFoods, char** list);
你的代码中也有其他的错误。
AllocateItem
是分配有效内存位置的对象,因此main中的stringArray[i]
()必须先赋值给这个内存位置,然后才能使用它。因为在此之前,它只是一个指向垃圾的未初始化指针。因此,您不能strcpy(stringArray[i], words)
。请记住,该函数不仅仅分配了一块内存,而且用有效的数据填充了它。所以设置指针指向那个数据就足够了,不需要复制任何东西。word
变量没有任何用途,您还可以编写以下内容:free(words)
是错误的,这将只释放最后分配的内存。对于每个malloc
调用,您必须有一个对应的free
调用!因此它应该是:wfsdck302#
当你像这样声明一个字符串变量时:字符串[10];你的计算机实际上声明了一个指针,但是分配了足够的内存来自动保存10个字符,你会看到如果你解引用它,你会得到你的字符串的第一个字符。
关于你的strcpy在第20行不起作用,if不起作用,因为你在for循环中创建了i变量,当你这样做的时候,变量在循环结束时消失,所以你不能在代码中的任何地方使用它。
关于你的第40行,你可以用至少两种不同的方式来使用指针,第一种是在函数中传递一个变量作为指针,这样你就不必在函数的末尾返回它,就像这样:
这里你需要解引用它,但是如果你给指针分配了内存,你现在可以把它当作一个数组来使用,而不用解引用它。
在这里,你只需要释放字符串数组中2的一个指针。要释放所有指针,试试:
请告诉我,如果我没有对每件事都很清楚,或者我说的不够清楚