我习惯于声明像这样的可变函数:
int f(int n, ...);
Run Code Online (Sandbox Code Playgroud)
阅读C++编程语言时,我发现书中的声明省略了逗号:
int f(int n...); // the comma has been omitted
Run Code Online (Sandbox Code Playgroud)
看起来这个语法是特定于C++的,因为当我尝试使用C编译器编译时出现此错误:
test.c:1:12: error: expected ‘;’, ‘,’ or ‘)’ before ‘...’ token int f(int n...);
写作int f(int n, ...)
和int f(int n...
)之间有什么区别吗?
为什么这个语法添加了C++?
我刚刚发现这在C++中是非法的(但在C语言中是合法的):
#include <stdio.h>
#include <stdlib.h>
#define ARRAY_LENGTH(A) (sizeof(A) / sizeof(A[0]))
int accumulate(int n, const int (*array)[])
{
int i;
int sum = 0;
for (i = 0; i < n; ++i) {
sum += (*array)[i];
}
return sum;
}
int main(void)
{
int a[] = {3, 4, 2, 4, 6, 1, -40, 23, 35};
printf("%d\n", accumulate(ARRAY_LENGTH(a), &a));
return 0;
}
Run Code Online (Sandbox Code Playgroud)
它编译没有问题使用gcc -std=c89 -pedantic
但无法编译使用g++
.当我尝试使用它来编译它时,g++
我收到以下错误消息:
main.cpp:5:37: error: parameter 'array' includes pointer to array of unknown bound …
Run Code Online (Sandbox Code Playgroud) __attribute__((const))
和__attribute__((pure))
GNU C有什么区别?
__attribute__((const)) int f() {
/* ... */
return 4;
}
Run Code Online (Sandbox Code Playgroud)
VS
__attribute__((pure)) int f() {
/* ... */
return 4;
}
Run Code Online (Sandbox Code Playgroud) 我今天早些时候在programmers.stackexchange上发布了这个问题.我一直认为int (*)[]
它不会衰减到int **
函数参数中,但我得到了多个回答我的问题表明它确实存在.
我int (*)[]
在我的函数参数中使用了很多,但现在我变得非常困惑.
当我使用编译此函数时 gcc -std=c99 -pedantic -Wall
void function(int (*a)[])
{
sizeof(*a);
}
Run Code Online (Sandbox Code Playgroud)
我收到此错误消息:
c99 -Wall -pedantic -c main.c -o main.o
main.c: In function ‘function’:
main.c:3:11: error: invalid application of ‘sizeof’ to incomplete type ‘int[]’
make: *** [main.o] Error 1
Run Code Online (Sandbox Code Playgroud)
这表明*a
有类型int []
而不是int *
.
有人可以解释一下,如果在函数参数中int (*)[]
衰减int **
,并给我一些参考(可能来自标准文档),这证明了为什么会这样.
我可以使用这种技术指定scanf
要读取的最大字符数buffer
:
char buffer[64];
/* Read one line of text to buffer. */
scanf("%63[^\n]", buffer);
Run Code Online (Sandbox Code Playgroud)
但是如果我们在编写代码时不知道缓冲区长度怎么办?如果它是函数的参数怎么办?
void function(FILE *file, size_t n, char buffer[n])
{
/* ... */
fscanf(file, "%[^\n]", buffer); /* WHAT NOW? */
}
Run Code Online (Sandbox Code Playgroud)
此代码容易受到缓冲区溢出的影响,因为fscanf
不知道缓冲区有多大.
我记得以前见过这个,并开始认为这是解决问题的方法:
fscanf(file, "%*[^\n]", n, buffer);
Run Code Online (Sandbox Code Playgroud)
我的第一个想法是,*
in "%*[*^\n]"
意味着最大字符串大小传递一个参数(在这种情况下n
).这就是*
in 的含义printf
.
当我检查文档时,scanf
我发现它意味着scanf
应该丢弃结果[^\n]
.
这让我有些失望,因为我认为能够动态传递缓冲区大小是一个非常有用的功能scanf
.
有没有办法可以scanf
动态地传递缓冲区大小?
就像在这个例子中(在C中):
typedef int type;
int main()
{
char type;
printf("sizeof(type) == %zu\n", sizeof(type)); // Outputs 1
}
Run Code Online (Sandbox Code Playgroud)
输出始终是局部变量的大小type
.
当C++ struct
在每次使用结构之前删除了写入的需要时,它仍然保留了struct {type}
语法并引入了一个alias(class {type}
)来显式引用结构或类.
示例(在C++中):
struct type {
int m;
};
int main()
{
char type;
printf("sizeof(type) == %u\n", sizeof(type)); // Outputs 1
printf("sizeof(struct type) == %u\n", sizeof(struct type)); // Outputs 4
printf("sizeof(class type) == %u\n", sizeof(class type)); // Outputs 4
}
Run Code Online (Sandbox Code Playgroud)
我的问题是,是否有一种方法可以明确地引用typedef
C或C++中的a.sizeof(typedef type)
也许是喜欢的东西(但这不起作用).
我知道通常的做法是对变量和类型使用不同的命名约定以避免这种情况,但我仍然想知道是否有一种方法可以在langau中执行此操作或者如果没有.:)
我已经编程了C很长一段时间了.在这段时间里,我了解到在第一列放置预处理程序指令之前的"#"字符是一种常见的约定.
例:
#include <stdio.h>
int main(void) {
#ifdef MACRO1
#ifdef MACRO2
puts("defined(MACRO1) && defined(MACRO2)");
#else
puts("defined(MACRO1)");
#endif
#else
puts("!defined(MACRO1)");
#endif
return 0;
}
Run Code Online (Sandbox Code Playgroud)
当人们缩进他们的预处理器指令时,他们通常会这样做:
#include <stdio.h>
int main(void) {
#ifdef MACRO1
# ifdef MACRO2
puts("defined(MACRO1) && defined(MACRO2)");
# else
puts("defined(MACRO1)");
# endif
#else
puts("!defined(MACRO1)");
#endif
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我不认为我曾见过有人像这样格式化:
#include <stdio.h>
int main(void) {
#ifdef MACRO1
#ifdef MACRO2
puts("defined(MACRO1) && defined(MACRO2)");
#else
puts("defined(MACRO1)");
#endif
#else
puts("!defined(MACRO1)");
#endif
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我的问题是,如果C语言标准要求#
-character应该在第一列.
那么上面的第三个选择是否合法?
如果以上所有案件都合法,那么我想知道这是否合法.
#include <stdio.h>
int main(void) { …
Run Code Online (Sandbox Code Playgroud) c syntax conditional-compilation language-lawyer c-preprocessor
我是一名熟悉C和C++的程序员.我在自己的项目中使用过两种语言,但我不知道哪种语言比我更喜欢.
当我在C中编程时,我最想从C++中获取的功能std::vector
来自STL(标准模板库)
我仍然没有弄清楚我应该如何在C中表示增长的数组.到目前为止,我在我的项目中重复了我的内存分配代码.我不喜欢代码重复,我知道这是不好的做法所以这对我来说似乎不是一个很好的解决方案.
我前段时间考虑过这个问题,想出了使用预处理器宏实现通用向量的想法.
这是实现的样子:
#ifndef VECTOR_H_
#define VECTOR_H_
#include <stdlib.h>
#include <stdio.h>
/* Declare a vector of type `TYPE`. */
#define VECTOR_OF(TYPE) struct { \
TYPE *data; \
size_t size; \
size_t capacity; \
}
/* Initialize `VEC` with `N` capacity. */
#define VECTOR_INIT_CAPACITY(VEC, N) do { \
(VEC).data = malloc((N) * sizeof(*(VEC).data)); \
if (!(VEC).data) { \
fputs("malloc failed!\n", stderr); \
abort(); \
} \
(VEC).size = 0; \
(VEC).capacity = (N); \
} while (0) …
Run Code Online (Sandbox Code Playgroud) 在C++ 11中x
,y
我写这个的类型是什么?
int main()
{
auto x = true ? 1 : 1.0;
auto y = false ? 1 : 1.0;
std::cout << x << endl;
std::cout << y << endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud) 我正在阅读C FAQ,并在一个问题中发现它建议我使用rand() / (RAND_MAX / N + 1)
而不是更流行的方式rand() % N
.
这样做的原因是,当数字N
为低rand() % N
时,只使用几位rand()
.
我测试了不同的处理办法N
是2
在Windows和Linux,但不能注意到差别.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define N 2
int main(void)
{
srand(0);
printf("rand() %% N:\n");
for (int i = 0; i < 40; ++i) {
printf("%d ", rand() % N);
}
putchar('\n');
srand(0);
printf("rand() / (RAND_MAX / N + 1):\n");
for (int i = 0; i < …
Run Code Online (Sandbox Code Playgroud)