当我创建一个遍历字符串的程序时,我使用了char *类型的变量。但是我发现我需要传递一个char **类型的变量。
如果我可以将char** line
转换为char* line
,那么一切都会完美无缺。有没有办法做到这一点?
编辑:这是我的代码的顶部。这适用于char *变量,但除非我可以传递char** line
并将其转换为char*
int exiting(char* line, int argcptr){
printf("char* line = %s\n", line);
int words = argcptr;
char* linecpy = (char*) malloc(100);
char* arg1 = " ";
char* arg2 = " ";
strcpy(linecpy, line);
char* bin = strtok(linecpy, " "); //obtain the first word
if(words > 1){
linecpy += (strlen(bin) + 1);
arg1 = strtok(linecpy, " "); //the next word will be the first argument, if applicable
printf("arg1 = %s\n", arg1);
words--;
}
if(words > 1){
linecpy += (strlen(arg1) + 1);
arg2 = strtok(linecpy, " "); //if applicable, grab the third argument
}
//***exit [value]*** : exit the shell with the value. if no value given, exit with value 0.
if(strcmp(bin, "exit") == 0){
if(strcmp(arg1, " ") == 0){
printf("exiting with 0\n");
exit(0);
}
else{
int exitNum = atoi(arg1);
printf("exiting with %d\n", exitNum);
exit(exitNum);
}
}
...
答案 0 :(得分:2)
当您取消引用时,char **
指针变为char *
。
例如
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define N 10
int main(void) {
char **ppchar = malloc(sizeof(char *) * N);
*ppchar = malloc(100); // now it is a char *pointer and I allocate the memory for the chars
strcpy (*ppchar, "Hello world");
printf("the char string = %s\n", *ppchar); // referenced char ** pointer is char * now
printf("and the actual chars. First = %c and fourth = %c\n", *(*ppchar + 0), *(*ppchar + 3));
}
*(*ppchar + 0)
=== **ppchar
。
答案 1 :(得分:2)
当你有这样的功能时:
void doSomething ( char ** linePtr ) {
// ...
}
然后linePtr
是指向某个字符串指针的指针,因此调用者可能会这样调用它:
char * string = ...;
doSomething(&string);
如果你的函数需要一个字符串指针,你只需要读取指针指向的值:
void doSomething ( char ** linePtr ) {
char * line = *linePtr;
// ...
}
但请注意,char **
也可能是指向字符串指针数组的指针:
char ** strings[] = {
"String1", "String2", "String3", "String4", NULL
};
doSomething(strings);
在这种情况下,您需要知道数组长度:
void doSomething ( char ** linePtr, size_t arrayLength ) {
for (size_t i = 0; i < arrayLength; i++) {
char * line = linePtr[i];
// ...
}
}
或者数组必须如上所示以NULL结尾,然后你可以通过检查NULL找到它的结尾:
void doSomething ( char ** linePtr ) {
for (size_t i = 0; linePtr[i]; i++) {
char * line = linePtr[i];
// ...
}
}
这里还有一些指针魔法:
char c = 5;
char * cptr = &c; // `cptr` is the address of `c`
char ** cptrptr = &cptr; // `cptrptr` is the address of `cptr`
char * anotherCptr = *cptrptr; // `anotherCptr` is the address of `c`
char anotherC = *anotherCptr; // `anotherC` is now 5.
*cptr = 8; // Now `c` is `8`
char c2 = 12;
cptr = &c2;
*cptr = 16; // `c2` is now `16` but `c` has not changed again.
**cptrptr = 2; // `c2` is now 2. Why? As `cptrptr` still points to `cptr`,
// the fact that `cptr` points elsewhere now won't influence `cptrptr`.
char * aString = calloc(sizeof(char), 100); // 100 characters in memory
char ** aStringPtr = &aString;
char * anotherString = *aStringPtr; // `anotherString == aString`
// They both point to the same piece of memory now. When changing
// `anotherString[0]`, `aString[0]` changes as well.
另请注意,指针和数组在C中通常是可以互换的,因为C中的数组没有元数据,因此内存中只有单个值的数组实际上只是一个值:
char ca = 5;
char cb[1] = { 5 }; // The memory of `ca` and the one `cb` points to look identical!
char * captr = &ca;
char * cbptr = cb; // No `&`, as an array reference is a pointer.
char c = *captr; // Works.
c = captr[0]; // Works, too, albeit `ca` is no array!
c = cbptr[0]; // Works.
c = *cbptr; // Works, too, albeit `cb` is an array!
事实上,C中的数组订阅是语法糖。您可以随时写x[n]
而不是*(x+n)
,它将具有相同的效果。请注意,指针上的+
不会将指针移动n
个字节,它会将指针移动 n倍于x (<addr> + (n * sizeof(x))
)的大小。所以char *
指针可以是指向单个char
的指针,也可以是指向char值数组(char[]
)的指针,你无法用C语言告诉。