这是用C计算数组长度的众所周知的代码:
sizeof(array)/sizeof(type)
Run Code Online (Sandbox Code Playgroud)
但我似乎无法找出作为函数参数传递的数组的长度:
#include <stdio.h>
int length(const char* array[]) {
return sizeof(array)/sizeof(char*);
}
int main() {
const char* friends[] = { "John", "Jack", "Jim" };
printf("%d %d", sizeof(friends)/sizeof(char*), length(friends)); // 3 1
}
Run Code Online (Sandbox Code Playgroud)
我假设数组通过值复制到函数参数作为常量指针,并且对它的引用应解决此问题,但此声明无效:
int length(const char**& array);
Run Code Online (Sandbox Code Playgroud)
我发现将数组长度作为第二个参数传递为冗余信息,但为什么标准声明main如下:
int main(int argc, char** argv);
Run Code Online (Sandbox Code Playgroud)
请解释是否可以在函数参数中找出数组长度,如果是,那么为什么存在冗余main.
#include <iostream>
using namespace std;
void printarray (int arg[], int length) {
for (int n = 0; n < length; n++) {
cout << arg[n] << " ";
cout << "\n";
}
}
int main ()
{
int firstarray[] = {5, 10, 15};
int secondarray[] = {2, 4, 6, 8, 10};
printarray(firstarray, 3);
printarray(secondarray, 5);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
这段代码有效,但我想了解数组是如何传递的.
当printarray从main函数调用函数时,正在传递数组的名称.数组的名称是指数组的第一个元素的地址.这等同于int arg[]什么?
#include<stdio.h>
void print(int *arr[], int s1, int s2) {
int i, j;
for(i = 0; i<s1; i++)
for(j = 0; j<s2; j++)
printf("%d, ", *((arr+i)+j));
}
int main() {
int a[4][4] = {{0}};
print(a,4,4);
}
Run Code Online (Sandbox Code Playgroud)
这适用于C,但不适用于C++.
错误:
cannot convert `int (*)[4]' to `int**' for argument `1' to
`void print(int**, int, int)'
Run Code Online (Sandbox Code Playgroud)
为什么它在C++中不起作用?需要做出哪些改变?
#include<stdio.h>
void printd(char []);
int main(void){
char a[100];
a[0]='a';a[1]='b';a[2]='c';a[4]='d';
printd(a);
return 0;
}
void printd(char a[]){
a++;
printf("%c",*a);
a++;
printf("%c",*a);
}
Run Code Online (Sandbox Code Playgroud)
说明:我原以为会导致左值错误.但它正在处理任何错误并将bc作为输出.为什么这个递增数组"a"不是错误?
我该如何工作:
void foo(uint8_t a[]) { ... }
foo({0x01, 0x02, 0x03});
Run Code Online (Sandbox Code Playgroud)
它给了我一个错误:
error: cannot convert '<brace-enclosed initializer list>' to 'uint8_t* {aka unsigned char*}' for argument '1'
^
Run Code Online (Sandbox Code Playgroud) GMP提供了初始化和分配mpz_t的方法.
对mpz_init_set(a,b)的调用将分配给b的内容.但是,我认为,这会对b执行深层复制.
在我的项目中,我需要使用长达5,000,000的mpz_t数组(我们正在谈论640MB的内存),我正在使用的框架对这些类型执行各种赋值操作(我没有开发框架和重写它不是一个选项).最近,我意识到在大多数赋值之后,b的值被清除,因此深度复制已经可以像它一样使用的值似乎是不自然的.但是,框架的接口不允许这样做(使用mpz_t周围的包装器)并且需要花费很多努力来改变它(我仍然可以改变一些基本的东西).
我已经尝试了一个基于指向mpz_class的指针的解决方案,但令人惊讶的是,它根本没有提供性能提升.实际上它会降低执行速度(尽管没有在大型阵列上测试).
我的问题是:我可以浅滩复制一个mpz_t吗?下面给出的例子
class somewrapper
{
mpz_t v;
somewrapper(mpz_t x) //constructor: probably performing deep copy here as well
{
// the following line performs a deep copy(?) on x
// but x is not used. why not shallow copy it?
mpz_init_set(v, x);
}
somefunction() { }
}
Run Code Online (Sandbox Code Playgroud) 请考虑以下代码段:
void foo(int a[], int b[]){
static_assert(sizeof(a) == sizeof(int*));
static_assert(sizeof(b) == sizeof(int*));
b = a;
printf("%d", b[1]);
assert(a == b); // This also works!
}
int a[3] = {[1] = 2}, b[1];
foo(a, b);
Run Code Online (Sandbox Code Playgroud)
输出(无编译错误):
2
Run Code Online (Sandbox Code Playgroud)
我无法理解为什么b = a有效.即使数组可能衰减到指针,它们是否应该衰减到const指针(T * const)?
在 stackoverflow 上的其他地方(例如,此处,不幸的是,目前接受的答案是不正确的——但至少最高投票的答案是正确的),C 标准规定,在几乎所有情况下,数组char my_array[50]都将隐式转换为char *when它被使用,例如通过传递给一个函数 as do_something(my_array),给定一个声明void do_something(char *stuff) {}。也就是说,代码
void do_something(char *my_array) {
// Do something
}
void do_something_2(char my_array[50]) {
// Do something
}
int main() {
char my_array[50];
do_something(my_array);
do_something_2(my_array);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
由 gcc 编译,没有任何严格级别的警告。
然而,C11的第6.3.2.1.3规定,此转换不发生特别是如果一个写操作&my_array,或sizeof(my_array)(而且这些是唯一次时,不会发生这种转换)。后一条规则的目的对我来说很明显——sizeof数组等于指向第一个元素的指针的大小是非常混乱的,所以应该避免。
但是这条规则的第一部分的目的(与写作有关&my_array)完全没有让我明白。看,该规则使类型为&my_array(在 C 标准的表示法中)char (*)[50],而不是char *。这种行为什么时候有任何用处?确实,除了 - 目的之外sizeof,为什么该类型根本char (*)[50]存在?
例如,在 stackexchange(例如 …
这个问题建立在这个问题的基础上,它描述了以下内容如何等效:
int f(int a[10]) { ... } // the 10 makes no difference
int f(int a[]) { ... }
int f(int *a) { ... }
Run Code Online (Sandbox Code Playgroud)
在有关函数原型作用域的文档中,提供了以下示例:
int f(int n, int a[n]); // n is in scope, refers to first param
Run Code Online (Sandbox Code Playgroud)
这让我质疑以下内容在多大程度上是等效的:
// 1.
int f(int n, int a[n]) { ... }
int f(int n, int *a) { ... }
// my guess: exactly equivalent
// 2.
int x = 10; int f(int a[x]) { ... } …Run Code Online (Sandbox Code Playgroud) c arrays language-lawyer implicit-conversion function-declaration