小编Lun*_*din的帖子

C和C++中字符串文字的类型是什么?

C中字符串文字的类型是什么?是char *const char *const char * const

那么C++呢?

c c++ string const

60
推荐指数
2
解决办法
2万
查看次数

为什么数组的最大大小"太大"?

我和这个答案的印象相同,size_t标准总是保证足够大以容纳给定系统的最大可能类型.

但是,此代码无法在gcc/Mingw上编译:

#include <stdint.h>
#include <stddef.h>

typedef uint8_t array_t [SIZE_MAX];
Run Code Online (Sandbox Code Playgroud)

错误:数组'array_t'的大小太大

我在这里误解了标准中的某些内容吗?被size_t允许为给定的实现是否过大?或者这是Mingw的另一个错误?


编辑:进一步的研究表明

typedef uint8_t array_t [SIZE_MAX/2];   // does compile
typedef uint8_t array_t [SIZE_MAX/2+1]; // does not compile
Run Code Online (Sandbox Code Playgroud)

这恰好是相同的

#include <limits.h>

typedef uint8_t array_t [LLONG_MAX];           // does compile
typedef uint8_t array_t [LLONG_MAX+(size_t)1]; // does not compile
Run Code Online (Sandbox Code Playgroud)

所以我现在倾向于认为这是Mingw中的一个错误,因为根据有符号整数类型设置最大允许大小没有任何意义.

c gcc mingw size-t stdint

56
推荐指数
3
解决办法
9743
查看次数

如何创建类型安全枚举?

使用C中的枚举来实现类型安全是有问题的,因为它们基本上只是整数.实际上,枚举常量被定义为int标准的类型.

为了实现一点类型的安全性我用这样的指针做了一些技巧:

typedef enum
{
  BLUE,
  RED
} color_t;

void color_assign (color_t* var, color_t val) 
{ 
  *var = val; 
}
Run Code Online (Sandbox Code Playgroud)

因为指针具有比值更严格的类型规则,所以这会阻止这样的代码:

int x; 
color_assign(&x, BLUE); // compiler error
Run Code Online (Sandbox Code Playgroud)

但它不会阻止这样的代码:

color_t color;
color_assign(&color, 123); // garbage value
Run Code Online (Sandbox Code Playgroud)

这是因为枚举常量基本上只是一个int,可以隐式赋值给枚举变量.

有没有办法编写这样的函数或宏color_assign,即使对于枚举常量也可以实现完整的类型安全性?

c enums type-safety

54
推荐指数
4
解决办法
4058
查看次数

正确分配多维数组

这个问题的目的是提供一个关于如何在C中动态正确分配多维数组的参考.这是一个经常被误解的主题,即使在一些C编程书籍中也很难解释.因此,即使是经验丰富的C程序员也很难做到正确.


我从编程教师/书籍/教程中了解到,动态分配多维数组的正确方法是使用指针指针.

然而,SO上的几个高代表用户现在告诉我这是错误和不好的做法.他们说指针到指针不是数组,我实际上并没有分配数组,而且我的代码不必要地慢.

这就是我教我分配多维数组的方法:

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

int** arr_alloc (size_t x, size_t y)
{
  int** pp = malloc(sizeof(*pp) * x);
  assert(pp != NULL);
  for(size_t i=0; i<x; i++)
  {
    pp[i] = malloc(sizeof(**pp) * y);
    assert(pp[i] != NULL);
  }

  return pp;
}

int** arr_fill (int** pp, size_t x, size_t y)
{
  for(size_t i=0; i<x; i++)
  {
    for(size_t j=0; j<y; j++)
    {
      pp[i][j] = (int)j + 1;
    }
  }

  return pp;
}

void arr_print (int** pp, size_t x, size_t y) …
Run Code Online (Sandbox Code Playgroud)

c arrays dynamic-arrays dynamic-allocation variable-length-array

51
推荐指数
1
解决办法
4882
查看次数

如何使用指针从不同的函数访问局部变量?

我可以在不同的函数中访问局部变量吗?如果是这样,怎么样?

void replaceNumberAndPrint(int array[3]) {
    printf("%i\n", array[1]);
    printf("%i\n", array[1]);
}

int * getArray() {
    int myArray[3] = {4, 65, 23};
    return myArray;
}

int main() {
    replaceNumberAndPrint(getArray());
}
Run Code Online (Sandbox Code Playgroud)

上面一段代码的输出:

65
4202656
Run Code Online (Sandbox Code Playgroud)

我究竟做错了什么?"4202656"是什么意思?

我是否必须在replaceNumberAndPrint()函数中复制整个数组才能比第一次更多地访问它?

c c++ pointers local-variables

50
推荐指数
3
解决办法
3万
查看次数

字符串化 - 它是如何工作的?

我知道:

#define foo 4  
#define str(s) #s
Run Code Online (Sandbox Code Playgroud)

str(foo)写出:"foo"因为字符串化的第一个文本扩展的执行,但这样的:

 #define xstr(s) str(s)
 #define str(s) #s
 #define foo 4
Run Code Online (Sandbox Code Playgroud)

xstr(foo)写出:"4".

为什么?该过程涉及哪些步骤?

c c++ stringification c-preprocessor

50
推荐指数
2
解决办法
3万
查看次数

隐式类型促销规则

本文旨在用作关于C中隐式整数提升的常见问题解答,特别是由通常的算术转换和/或整数提升引起的隐式提升.

示例1)
为什么这会给出一个奇怪的大整数而不是255?

unsigned char x = 0;
unsigned char y = 1;
printf("%u\n", x - y); 
Run Code Online (Sandbox Code Playgroud)

例2)
为什么这会给"-1大于0"?

unsigned int a = 1;
signed int b = -2;
if(a + b > 0)
  puts("-1 is larger than 0");
Run Code Online (Sandbox Code Playgroud)

示例3)
为什么更改上例中的类型来short解决问题?

unsigned short a = 1;
signed short b = -2;
if(a + b > 0)
  puts("-1 is larger than 0"); // will not print
Run Code Online (Sandbox Code Playgroud)

(这些示例适用于16位或短16位的32位或64位计算机.)

c type-conversion implicit-conversion

50
推荐指数
2
解决办法
7417
查看次数

"保留用于任何用途"的含义是什么?

注意:这是一个问题,但我添加了,以防一些C++专家可以提供C++使用与C不同的措辞的基本原理或历史原因.


在C标准库规范中,我们有这个规范性文本,C17 7.1.3保留标识符(强调我的):

  • 所有以下划线开头的标识符以及大写字母或另一个下划线始终保留用于任何用途.
  • 所有以下划线开头的标识符始终保留用作普通和标记名称空间中具有文件范围的标识符.

现在我继续阅读各种受尊敬的C专家的答案,他们声称编译器或标准库可以使用下划线+大写或双下划线的标识符.

是否"保留用于任何用途"是指保留给除C语言本身的未来扩展之外的任何人?这意味着实现容许使用它们.

虽然上面的第二个短语,关于单个前导下划线似乎是针对实现?

通常,C标准的编写方式要求编译器供应商/库实现者是典型的读者 - 而不是应用程序员.

值得注意的是,C++的措辞非常不同:

  • 每个包含双下划线(__)或以下划线后跟大写字母(2.11)开头的名称都保留给实现以供任何使用.

(请参阅在C++标识符中使用下划线有哪些规则?)

这可能是C和C++之间的混淆,语言在这里有所不同吗?

c c++ language-lawyer c-standard-library

50
推荐指数
4
解决办法
4007
查看次数

远指针和近指针有什么区别?

谁能告诉我C中的far指针和near指针之间的区别?

c pointers

49
推荐指数
3
解决办法
6万
查看次数

如何正确分配新的字符串值?

我试图了解如何以最干净/最安全的方式解决C中的这个微不足道的问题.这是我的例子:

#include <stdio.h>

int main(int argc, char *argv[])
{
    typedef struct
    {
        char name[20];
        char surname[20];
        int unsigned age;
    } person;

    //Here i can pass strings as values...how does it works?
    person p = {"John", "Doe",30};

    printf("Name: %s; Age: %d\n",p.name,p.age);
    // This works as expected...
    p.age = 25;
    //...but the same approach doesn't work with a string
    p.name = "Jane";

    printf("Name: %s; Age: %d\n",p.name,p.age);

    return 1;
}
Run Code Online (Sandbox Code Playgroud)

编译器的错误是:

main.c:在函数'main'中:main.c:18:错误:从类型'char*'分配类型'char [20]'时出现不兼容的类型

我知道C(不是C++)没有字符串类型而是使用字符数组,所以另一种方法是更改​​示例结构以保存字符指针:

#include <stdio.h>

int main(int argc, char *argv[])
{
    typedef …
Run Code Online (Sandbox Code Playgroud)

c string struct strcpy

45
推荐指数
3
解决办法
16万
查看次数