how to resolve Undeclared array referenced error in sas? - sas

Consider the following codes:
data;
x=var{89,90,78,98,87,786,69,90,92,88};
y=std{89,90,78,98,87,76,69,90,92,88};
run;
I get the following errors:
1 data;
2 x=var{89,90,78,98,87,786,69,90,92,88};
ERROR: Undeclared array referenced: var.
ERROR: Variable var has not been declared as an array.
3 y=std{89,90,78,98,87,76,69,90,92,88};
ERROR: Undeclared array referenced: std.
ERROR: Variable std has not been declared as an array.
4 run;

In SAS the arguments to a function are enclosed in parenthesis.
Try
data;
x = var (89,90,78,98,87,76,69,90,92,88); * Variance;
y = std (89,90,78,98,87,76,69,90,92,88); * Standard deviation;
run;
The ERROR: messages appear because array subscripting references are made with bracketing square brackets ([]), curly braces ({}) or parenthesis (()). Declared array names can override function names, so be careful with that.
Your source code
x = var{89,90,78,98,87,786,69,90,92,88};
is actually telling SAS you want to retrieve a value from a 10-dimensional array.
Functions can also process arrays if you add a of to the arguments list.
data x;
* initialize temporary array of 10 values;
array m(10) _temporary_ (89,90,78,98,87,76,69,90,92,88);
* measure the array of values;
x = var (of m(*));
y = std (of m(*));
run;

Related

Is it possible to use the ternary operator "?" to fill an array list in C/C++?

This is probably a dumb questions. I'm modifying a code developed by someone else. I need to particularize the value of some chars array based on a logic variable ThreeDim. I'm trying to do this without success.
int VarNumber = ThreeDim==1 ? 3 : 2;
const char* VarList [] = ThreeDim==1 ? {"X","Y","Z"} : {"X","Y"};
But the compiler is giving me errors like
error: expected ‘;’ before ‘}’ token
error: initializer fails to determine size of ‘VarList’
VarList needs to be a const char* due to downstream requirements. And its size should be VarNumber. Thanks
You might consider using the preprocessor, #define THREE_DIM, and then use #ifdef to select one or the other code to compile:
#define THREE_DIM
#ifdef THREE_DIM
int VarNumber = 3;
const char* VarList [] = {"X","Y","Z"};
#else
int VarNumber = 2;
const char* VarList [] = {"X","Y"};
#endif
I don't think you can do this with different sized array initializers. However, you can put a conditional expression in the initializer:
const char* VarList [] = {"X", "Y", ThreeDim == 1 ? "Z" : nullptr};
This will always give you a 3 element array with the last element either "Z" or a null pointer.
No, because e.g. {"X","Y","Z"} is not an expression. It's handled specially by the compiler for variable definitions.
And if you're programming C++ you should be using std::vector and std::string instead, then it would be very simple (but verbose):
std::vector<std::string> VarList = ThreeDim==1 ?
std::vector<std::string>{{"X","Y","Z"}} :
std::vector<std::string>{{"X","Y"}};
As per C11 6.7.9, arrays aren't initialized with an expression but with an initializer list; these are two different syntactical elements and can't be mixed. This derives from the fact that arrays aren't assignable, and treating one as a value (as opposed to a value that decays to a pointer) therefore doesn't make sense. Since they aren't values, there's no way to create a legal expression that passes around whole arrays.
The closest direct analogue to what you're asking for would be:
const char** VarList = ThreeDim==1 ? (const char*[]){"X","Y","Z"} : (const char*[]){"X","Y"};
...but this comes at the cost of changing the type of VarList, and is probably not what you want.

Store pointer to 2d array [duplicate]

This question already has answers here:
How do I declare a 2d array in C++ using new?
(29 answers)
Closed 8 years ago.
So I have a private member in the class Map:
char **_map;
I then try to initialize the pointer array to a two dimensional char array like this:
std::vector<std::string> contents = StringUtils::split(_mapInfo.getContents(), ' ');
const int x = StringUtils::toInt(contents.at(0));
const int y = StringUtils::toInt(contents.at(1));
_map = new char[x][y];
Basically the contents vector contains two strings, which I then convert into integers. I then try to initialize the map array but I receive this error:
Error 1 error C2540: non-constant expression as array bound
And this:
Error 2 error C2440: '=' : cannot convert from 'char (*)[1]' to 'char **'
And finally this:
3 IntelliSense: expression must have a constant value
The last error references the variable y
Can anyone explain what is happening and how I can fix it?
The initialization of 2d array is as following;
char **_map;
_map = new char*[rowsize];
for(int row = 0; row < rowsize; ++row)
{
_map[row] = new char[columnsize]
}

Passing arrays to functions

I am currently in an introductory c++ class and am working assignment that sorts data. We recently covered structs and I decided to use structs to approach the problem rather than create 3 arrays to hold the information from our data file.
The trouble i'm having is when i'm trying to pass my struct to my function.
Here is my error:
analyze_data.cpp: In function ‘int main()’:
analyze_data.cpp:76: error: conversion from ‘weather*’ to non-scalar type ‘weather’ requested
analyze_data.cpp: In function ‘int find_pos_of_smallest(weather, int, int)’:
analyze_data.cpp:110: error: no match for ‘operator[]’ in ‘data[pos]’
analyze_data.cpp:110: error: no match for ‘operator[]’ in ‘data[pos_of_smallest]’
I don't understand the error from line 76. I have done some research about passing structs to functions, and what i found was adding the "&" in the type declarations. However, i have no idea what it does or why i would need to do that as we haven't covered it in class. I also did try it, but i just got a different set of errors. So i figured i'd not post those and just start from what i know.
Here is my code
/*
Program name: Analyze data
Program discription: This program will read a data file named data.txt.
This data file is expected to be formated in a specific way and contain
specific weather information. The program will analyize this data and
return max, min temperatures, 'perfect days', how many cold fronts per
year, 10 coldest and hottest days in a year and finally find the 5
median days of the year.
Date: 10/1/2012
*/
#include <iostream>
#include <fstream>
using namespace std;
/*
* Declare struct's here
*
*/
struct weather
{
string date;
int high;
int low;
};
/*
* Forward declaration of a function. This declares the function,
* but does not define it. (Notice that there is no code, just
* a function header with a semicolon after it.
*
*/
int find_pos_of_smallest (weather data, int start_pos, int end_pos);
/* Our main function.
*
* Parameters:
* none
*
* Return value:
* 0 if we complete successfully, 1 if there was an error.
*/
int main()
{
//read the data file
ifstream weather_data("data.txt");
//declare array size, and then create array using struct
int days = 365;
weather data[days];
//store the data.txt in the array and then close the file
for (int i=0; i<days; i++)
{
weather_data >> data[i].date;
weather_data >> data[i].high;
weather_data >> data[i].low;
}
weather_data.close();
ofstream data_results ("results.txt");
// create the first 3 lines of the output reults in the following formated
data_results << "Assignment #5\n"
<< "CS 1410/2000\n"
<< "Jonathan Larsen\n";
/*
for(int i=0; i<3; i++)
{
cout<<data[i].date << " "<<data[i].high << " " << data[i].low<<endl;
}
cout<<endl;
*/
cout<<find_pos_of_smallest(data, 0, days)<<endl;
return 0; //no error so return a zero
}//end of program
/**** FUNCTIONS ****/
/* Write down exactly what the function will do (a postcondition).
* Write down what is required to use the function (any preconditions).
* Write down any other behavior or comments that will help a programmer.
*
* Parameters: (list parameters by type and name, and explain them)
* int example -- an example parameter
*
* Returns:
* double -- an example return value
*/
/* Returns the position of the smallest value found in the specified
* subarray. (Only the elements in the subarray
* between start_pos and end_pos inclusive are checked.)
*
* Parameters:
* d - a data array
* start_pos - the first position to check
* end_pos - the last position to check
*/
int find_pos_of_smallest (weather data, int start_pos, int end_pos)
{
int pos_of_smallest = start_pos;
for (int pos = start_pos+1; pos <= end_pos; pos++)
if (data[pos].low < data[pos_of_smallest].low)
pos_of_smallest = pos;
return pos_of_smallest;
}
You are passing an array to your function. Your function needs to either take type weather[] or weather*. For instance:
int find_pos_of_smallest (weather* data, int start_pos, int end_pos)
You should note that even if you were not passing an array but a regular struct, you should still pass by reference. Either pass a pointer (weather*) and use the dereference memeber operator (->) or pass by reference (weather&) and use the normal member operator(.). This is because passing by value (no */&) causes the struct to be copied into a new value on the stack which can take a considerable amount of time for large values (for instance if the string gets large).
You need to pass your array as a pointer:
int find_pos_of_smallest (weather *data, int start_pos, int end_pos)
Declaring the parameter as weather data means just a single instance of the struct. Making it a pointer means you can pass an array (the pointer will get the address of the first element in the array, and when you index it with data[pos] you will get the relevant element in that array).
Whenever you declare an array of something, like your data array, writing the array's name by itself (in this case, data) in subsequent code is, confusingly enough, actually equivalent to writing
&(data[0])
which means "the address of the first element of the data array". This is how arrays are usually "passed" into functions in C and C++ -- by passing the address of their first element. It's done this way because the usual way of passing other types of arguments -- namely, copying them -- would be very wasteful in the case of large arrays. It also has the side-effect of allowing any changes that the function makes to the array to be visible to the calling code (sometimes this is needed, sometimes not).
How do you work with that address inside the function? You use a pointer-to-weather:
int find_pos_of_smallest(weather* data, int start_pos, int end_pos)
A pointer is a variable that contains the address of some other thing. You can access the pointed-to thing using the * indirection operator, the -> operator (if the pointed-to thing is a struct or class), and, conveniently, the array subscripting operator []: e.g. inside find_pos_of_smallest(),
data[5]
refers to the sixth element in an array of weather elements starting at the address stored inside the pointer data.

Structure error: Not recognized even though it is included

More quetions:
i get an unrecognized 'eld' from mai structure.
header contains:
const int c=10;
struct Array
{
int n;
int els[c];
};
The error i get is:
error: request for member 'els' in 'A', which is of non-class type 'Array [(((unsigned int)(((int)a) + -0x000000001)) + 1)] {aka Array [(((unsigned int)(((int)a) + -0x000000001)) + 1)]}'
Code:
Array arrayInp()
/* Create 2 vectors by the length defined by the user*/
{
int a,b,i;
cout<<"enter length of the first array: ";
cin>>a;
cout<<"enter length of the second array: ";
cin>>b;
Array A[a],B[b];
cout<<"insert first array:";
for (int i=0;i<a;i++)
{
cin>>A.els[i];
}
cout<<"insert second array:";
for (int i=0;i<a;i++)
{
cin>>B.els[i];
}
return A,B;
}
One more error, my return isent right can someone explain me a way how to return the array structures from the functions?
after build errors:
..\scr\main.cpp:32:10: warning: left operand of comma operator has no effect [-Wunused-value]
..\scr\main.cpp:32:10: error: could not convert '(0, ((Array*)(& B)))' from 'Array*' to 'Array'
..\scr\main.cpp:11:10: warning: unused variable 'i' [-Wunused-variable]
..\scr\main.cpp:33:1: warning: control reaches end of non-void function [-Wreturn-type]
This:
Array A[a]
defines an array of Array called A. You need to index A to access the members of Array or (I suspect this was your intention) change declarations to:
Array A, B;
Just to point out that variable length arrays are not standard C++ (I think they are a GCC extension).
The return statement:
return A,B;
is using the comma operator. In this case B will returned and is the cause of warning: left operand of comma operator has no effect.
The unused variable i warning is complaining that the i declared at the beginning of the function int a, b. i; is unused, this is due to redeclaration of i in both for loops: either remove the i from top declaration or don't redeclare in for loops.
Without seeing the full source code, I suspect the warning: control reaches end of non-void function is because there is no return 0; in int main().
You probably want A[i].els, not A.els[i].
I addition to hmjd comment, I think I should point out that this has already been implemented but better by the standard library; it is almost always better to use std library constructs where possible because they are well know to other C++ developers, their functionality is well documented and finally they have a uniform interface which integrates with other standard features (such as standard algorithms).
There are two construct you can use
The fixed size:
std::array<int, 6> array_; //an array of six elements
And the resizable
std::vector<int> vector_(6); //a container of six elements.
http://en.cppreference.com/w/cpp/container/array
http://en.cppreference.com/w/cpp/container/vector

Unfamiliar use of 'new' for memory allocation (C++)

I am working on some legacy code. I have the following data types:
typedef struct {
char *name ;
ColumnType type ;
unsigned pos ; //column position in table
CellData **data ; //ptr to list of cells in column
}Column ;
struct _table {
char name[TABLE_NAME_LEN+1] ;
unsigned int num_rows ;
unsigned int num_cols ;
Column **cols ; //ptr to list of columns
};
struct _table m_
In the source code, there is the following statement:
m_table.cols = new Column*[m_table.num_cols];
I am familiar with new[], but I'm no sure what the multiplication operator is doing there - can any explain?
It's not multiplication. The symbol * has many, many completely different meanings in C++, all depending on context.
In your case, you're creating a dynamic array of Column*, i.e. of pointers to Column.
In other words, you're saying new T[N];, where T = Column*.
It's not a multiplication operator. It's instead allocating an array of Column* (pointer to Column type). The resulting array stores pointer values
m_table.cols = new Column*[m_table.num_cols];
m_table.cols[0] = Column(); // Error: Expected Column* got Column
m_table.cols[0] = new Column(); // Ok
In your case Column* is a type (for pointers to instances of Column class) and you create an array of them.
It's not a multiplication operator. It's allocating an array of pointer-to-Column, rather than an array of Column.
It's not a multiplication operator, it's a pointer specification i.e. "pointer to Column".
The * denotes a pointer. So you're creating an array of Column pointers.