如下所示,我希望将一个由char **x定义的变量作为只读传递给一个函数.

一本参考书显示了线性搜索源代码,它通过将变量作为由const int a[]定义的临时参数传递给search函数来对由char *x定义的变量执行线性搜索.

所以我突然想到了一个 idea ,如果是弦呢?然后我编写了下面的代码.

GCC、叮当和MSVC的分析可以找到here个.

// Linear Search

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int scanf_s(const char *format ,...); // for gcc and clang environment
// int search(const char **a, int n, char *key) {       //※[1]not allowed in c lang specification⇒NG
// int search(char * const *a, int n, char *key) {      //※[2]⇒NG
// int search(const char * const *a, int n, char *key) {    //※[3]warning occured in gcc and clang!!
// int search(char const * const *a, int n, char *key) {//※[4]same as above
// int search(const char * const a[], int n, char *key) {//※[5]same as above
// int search(const char *a[], int n, char *key) {      //※[6]I thought this was ok, but warning occured in gcc and clang!!
int search(char **a, int n, char *key) {            //in conclusion, gcc,clang and MSVC only allowing this!!
    int i = 0;

    for (i = 0; i < n; i++) {
        if (strcmp(a[i], key) == 0)
            return i;
    }
    return -1;

    /* or while style!! the reference book shows this style!!
    while (1) {
        if (i == n)
            return -1;
        if (strcmp(a[i], key) == 0)
            return i;
        i++;
    }
    */
}

int main(void) {
    char **x;
    char *ky;
    int nx;
    int idx;
    int i;

    puts("Linear Search");
    printf("How many Elements??:");
    scanf_s("%d", &nx);
    
    x = malloc(sizeof(char*) * nx);
    if (x == NULL) {
        printf("Pointer to Pointer x malloc failed!!\n");
        exit(EXIT_FAILURE);
    }

    for (i = 0; i < nx; i++) {
        printf("x[%d]:", i);
        x[i] = malloc(sizeof(char) * 35);
        if (x[i] == NULL) {
            printf("Pointer Array x[] malloc failed!!\n", i);
            exit(EXIT_FAILURE);
        }
        scanf_s("%s", x[i], 35);
    }

    printf("Target Value:");
    ky = malloc(sizeof(char) * 35);
    if (x == NULL) {
        printf("target value malloc failed!!\n");
        exit(EXIT_FAILURE);
    }
    // Or
    // ky = calloc(35, sizeof(char));
    scanf_s("%s", ky, 35);

    idx = search(x, nx, ky);

    if (idx == -1)
        puts("no target value.");
    else
        printf("%s is in x[%d]!!\n", ky, idx);

    free(ky);
    for (i = 0; i < nx; i++) {
        free(x[i]);
    }
    free(x);
    system("pause");
    return 0;
}

代码为const的代码会使GCC和Clang显示警告,尽管msvc可以在没有任何警告的情况下进行编译,如注释(※[1]~[6])所示.

那么,如何在search函数必须接受由char **x定义的变量作为只读参数的情况下编写代码呢?

推荐答案

编译器希望数组中的字符串为const char*类型.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>

#define STRING_LENGTH 36

int scanf_s(const char *format ,...);

unsigned int search(const char* const stringArray[], unsigned int stringCount, const char* stringToSearch)
{
   for(unsigned int i = 0; i < stringCount; i++)
   {
      if(strcmp(stringArray[i], stringToSearch) == 0)
      {
         return i;
      }
   }

   return UINT_MAX;
}

int main(void)
{
   printf("Enter the count of strings: ");

   unsigned int strCount;
   scanf_s("%u", &strCount);

   char* *strArray = malloc(sizeof(char*) * strCount);
   if(strArray == NULL)
   {
       printf("Could not get memory for the string array!\n");
       return EXIT_FAILURE;
   }

   for(unsigned int i = 0; i < strCount; i++)
   {
       strArray[i] = calloc(sizeof(char), STRING_LENGTH);
       if(strArray[i] == NULL)
       {
          printf("Could not get memory for the next string!\n");
          return EXIT_FAILURE;
       }

       printf("Enter %uth string (%i characters at most): ", (i + 1), (STRING_LENGTH - 1));
       scanf_s("%s", strArray[i], STRING_LENGTH);
   }

   char* strToSearch = calloc(sizeof(char), STRING_LENGTH);
   if(strToSearch == NULL)
   {
      printf("Could not get memory for the string to be searched!\n");
      return EXIT_FAILURE;
   }

   printf("Enter string to be searched (%i characters at most) : ", (STRING_LENGTH - 1));
   scanf_s("%s", strToSearch, STRING_LENGTH);

   unsigned int result = search((const char* const*)strArray, strCount, strToSearch);
   if(result != UINT_MAX) {
      printf("String found at index: %u\n", result);
   } else {
      printf("String was not found!\n");
   }

   free(strToSearch);
   for(unsigned int i = 0; i < strCount; i++)
   {
       free(strArray[i]);
   }
   free(strArray);

   return EXIT_SUCCESS;
}

我在您提供的链接中try 了此代码. 当我和GCC一起编译并运行它时,样例输出如下:

Enter the count of strings: 3
Enter 1th string (35 characters at most): Goodbye
Enter 2th string (35 characters at most): Cruel
Enter 3th string (35 characters at most): World
Enter string to be searched (35 characters at most) : Cruel
String found at index: 1

判断here

编辑:我想添加更多信息.

const char*char const*是一回事.

const char* const arr[]等于const char* const* const arr.

使用const char* const* const arr的目的是保护ARR的地址、ARR的内容和ARR的内容.

注意:我决定准备一个关于字符指针的简短教程.很可能明天下午就能洗好了.:)

C++相关问答推荐

ARM上的Modulo Sim Aarch 64(NEON)

ISO_C_BINDING,从Fortran调用C

返回一个包含数组的 struct

为什么GCC C23中的关键字FALSE不是整数常量表达式?

非常大的数组的大小

Char变量如何在不使用方括号或花括号的情况下存储字符串,以及它如何迭代到下一个字符?

如何识别Linux中USB集线器(根)和连接到集线器(根设备)的设备(子设备)?

在基本OpenGL纹理四边形中的一个三角形中进行渲染

如何按顺序将所有CSV文件数据读入 struct 数组?

GTK函数调用将完全不相关的char* 值搞乱

Caesar密码调试:输出文本末尾的问号和随机字符

从C中的函数返回静态字符串是不是一种糟糕的做法?

从CentOS 7到Raspberry PI 2B的交叉编译-无法让LIBC和System Include标头一起工作

为什么会导致分段故障?(C语言中的一个程序,统计文件中某个单词的出现次数)

将复合文字数组用作临时字符串缓冲区是否合理?

共享内存未授予父进程权限

无法理解 fgets 输出

GDB 跳过动态加载器代码

free后内存泄漏?

C11 嵌套泛型