C array basic operation and manipulation in comparison to Python
I am switching from Python to C code for the purpose of my project. As I try to manipulate an array, it is very different from what I used to do in python. So I just want to know some "equivalent" operations for an array in C and Python.
So for numpy array in Python, we can directly sum(or other operations) up two arrays elementwise easily. In a sense, I think numpy array is like a virtual "matrix" that you can manipulate with as if it is stored as a whole(at least appear to).
For C array, it looks like a different animal. From what I could search out from the internet, I have to use for loop in order to do these basic operations. I think an array in C is just a set of values that are stored in addresses next to each other in order.
I know that C is much faster than Python, but I also know for loop is a nasty thing that should be avoided as possible in Python. Isn't these for loops in C slow the program down?(though I think when I use numpy module in Python, the module takes care of these for loops implicitly)
I also get a confusion about pointer. Consider this function that takes in a 1D array:
int myfunc(int *myarray);
{
int sum=0;
for(int i=0; i<sizeof(myarray); i++)
{
sum += myarray[i];
}
return sum
}
Suppose I input some array say "arr", then I let:
*myarray = arr
Thus, later in the function when I am calling lines such as:
sum += myarray[i]
I am actually doing this:
sum += &arr
Which is really confusing. For me, it looks like I am directly adding addresses of variables with values of other variables. Is this code wrong or I misunderstand pointer?
1 answer
-
answered 2017-06-17 19:48
Michaël Roy
In your function:
int myfunc(int *myarray); // The ; at the end of this line will // generate a compiler error. { int sum=0; for(int i=0; i<sizeof(myarray); i++) // size of int* is the size of a pointer // 4 for 32bit app, or 8 for 64 bits apps { sum += myarray[i]; } return sum }
You should pass the number of elements to your array as a parameter for it to work:
int myfunc(int *myarray, int count) { int sum=0; for (int i = 0; i < count; i++) { sum += myarray[i]; } return sum; }
[Edit] When you do this:
sum += &arr;
You are incrementing
sum
with the address of variablearr
.Whereas:
sum += array[i];
increments
sum
with theint
value stored at the(i+1)th
position ofarray
.The following statement:
*myarray = arr;
Stores the value of arr into the value pointed to by myarray, this is equivalent to writing:
myarray[0] = arr;
See also questions close to this topic
-
How python object memory works for int less than -5 and greater 256
In my understanding, all things in python are object and some of them per-allocate memory to them (for int the range is from -5 to 256).
My question is if the address not per-allocate, does it create in fly?for example:
print id(256) a = 256 print id(a) 36609008 36609008
this example indicates variable a is referring the object 256's memory, thus they have same address.
print id(300) a = 300 print id(a) 106711544 106708304
for the example above:
- does python create two objects? (it seems yes)
- why -5 to 256?
- would those per-allocated object be reused to create new objects?
-
Guess the Letter Program Not Working?
I'm creating a very basic "guess the letter" game. My code is below. When I run the program and enter one of the correct listed letters, it still runs the code as if it was an incorrect letter. What do I need to fix?
letters = ("M","K","O","W","X","S","A") guess = input("Guess a letter: ") while guess.lower() != letters: print("Incorrect!") input("Guess a letter: ") if guess.lower() == letters: print(guess,"is correct!") input("Press Enter to Continue")
When the code is working properly, it should display something like this:
Guess a letter: p Incorrect! Guess a letter: q Incorrect! Guess a letter: m M is correct!
-
How to parse the data in <pre> tag using beautifulsoup?
when I am trying to scrape the data from the following website
I got this from bedbathbeyond website and if I use request and beautifulsoup, I can't get anything. Why is that?
code:
r = requests.get(url) soup = BeautifulSoup(r.content,'lxml') soup.find_all('span', class_ = 'BVRRReviewAbbreviatedText')
the return value is empty: []
-
Program that checks for a valid Unix FTP Command (Not working)
I can compile this program in Unix (Sun-Solaris) to be specific, but I cant get it to run (Im un a Unix course and all of our programs/assignments are to be done on the schools servers). Hes only been teaching us C in the last 2 weeks of the course. Im fairly new to C and cant figure out why it is not working. Any help would be appreciated. I did some research on the error but unfortunately the methods I tried/found online either didnt work or im not doing them properly.
Code below.
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <assert.h> char** splitString(char* inputString, const char delim) { char** output = 0; size_t c = 0; char* temp = inputString; char* final_space = 0; char delimiter[2]; delimiter[0] = delim; delimiter[1] = 0; while(*temp) { if(delim == *temp) { c++; final_space = temp; } temp++; } c += final_space < (inputString + strlen(inputString) - 1); c++; output = malloc(sizeof(char*) * c); if(output) { size_t index = 0; char* output = strtok(inputString, delimiter); while(output) { assert(index < c); *(output + index++) = strdup(output); output = strtok(0, delimiter); } assert(index == c - 1); *(output + index) = 0; } return output; } void main() { char input[50]; char** splitInput = NULL; int rs; printf("please enter a Unix FTP cmd. The program will check to see if it is a valid cmd: "); gets(input); splitInput = splitString(input, ' '); printf("input[%s]", *(splitInput)); rs = strcmp(*(splitInput), "ascii"); if(rs == 0) { printf("ascii is a valid ftp command\n"); return; } rs = strcmp(*(splitInput), "recv"); if(rs == 0) { printf("recv is a valid ftp command\n"); free(splitInput); printf("the entered cmd is %s", *(splitInput + 1)); return; } rs = strcmp(*(splitInput), "get"); if(rs == 0) { printf("get is a valid ftp command\n"); free(splitInput); printf("the entered cmd is %s", *(splitInput + 1)); return; } rs = strcmp(*(splitInput), "send"); if(rs == 0) { printf("send is a valid ftp command\n"); free(splitInput); printf("the entered cmd is %s", *(splitInput + 1)); return; } rs = strcmp(*(splitInput), "put"); if(rs == 0) { printf("put is a real Unix FTP cmd\n"); free(splitInput); printf("the entered cmd is %s", *(splitInput + 1)); return; } rs = strcmp(*(splitInput), "rmdir"); if(rs == 0) { printf("rmdir is a real Unix FTP cmd\n"); printf("the entered cmd is %s", *(splitInput + 1)); return; } rs = strcmp(*(splitInput), "mkdir"); if(rs == 0) { printf("mkdir is a real Unix FTP cmd\n"); free(splitInput); printf("the entered cmd is %s", *(splitInput + 1)); return; } rs = strcmp(*(splitInput), "rmdir"); if(rs == 0) { printf("rmdir is a real Unix FTP cmd\n"); free(splitInput); printf("the entered cmd is %s", *(splitInput + 1)); return; } rs = strcmp(*(splitInput), "ls"); if(rs == 0) { printf("ls a real Unix FTP cmd\n"); free(splitInput); printf("the entered cmd is %s", *(splitInput + 1)); return; } rs = strcmp(*(splitInput), "cd"); if(rs == 0) { printf("cd is a real Unix FTP cmd\n"); free(splitInput); printf("the entered cmd is %s", *(splitInput + 1)); return; } rs = strcmp(*(splitInput), "status"); if(rs == 0) { printf("status is a valid ftp command\n"); return; } rs = strcmp(*(splitInput), "quit"); if(rs == 0) { printf("quit is a valid ftp command\n"); return; } else { printf(*(splitInput), " isn't a real Unix FTP cmd"); } return; }
This is a screenshot of the error I get: Error inside PuTTy console
-
C - Algorithm for Bitwise operation on Modulus for number of not a power of 2
I know that modulo of power of 2 can be calculated using bitwise operator
x % 2^n == x & (2^n - 1).
But I am wondering is there any generalized bitwise algorithm exists to find the modulus of any number is not a power of 2. For example,
7%5
Thank you in advance.
-
Piping/dup2() not working properly (Implementing Unix Shell in C)
I'll post my code first, then explain the problem I'm having:
#include <stdio.h> #include <sys/wait.h> #include <unistd.h> #include <string.h> #include <stdlib.h> #include <fcntl.h> #define MAX_ARGS 20 #define BUFSIZE 1024 int get_args(char* cmdline, char* args[]) { int i = 0; /* if no args */ if((args[0] = strtok(cmdline, "\n\t ")) == NULL) return 0; while((args[++i] = strtok(NULL, "\n\t ")) != NULL) { if(i >= MAX_ARGS) { printf("Too many arguments!\n"); exit(1); } } /* the last one is always NULL */ return i; } void execute(char* cmdline) { int pid, async, oneapp; char* args[MAX_ARGS]; char* args2[] = {"-l", NULL}; int nargs = get_args(cmdline, args); if(nargs <= 0) return; if(!strcmp(args[0], "quit") || !strcmp(args[0], "exit")) { exit(0); } printf("before the if\n"); printf("%s\n",args[nargs - 2]); int i = 0; // EDIT: THIS IS WHAT WAS SUPPOSED TO BE COMMENTED OUT /* while (args[i] != ">" && i < nargs - 1) { printf("%s\n",args[i]); i++; } */ // Presence of ">" token in args // causes errors in execvp() because ">" is not // a built-in Unix command, so remove it from args args[i - 1] = NULL; printf("Escaped the while\n"); // File descriptor array for the pipe int fd[2]; // PID for the forked process pid_t fpid1; // Open the pipe pipe(fd); // Here we fork fpid1 = fork(); if (fpid1 < 0) { // The case where the fork fails perror("Fork failed!\n"); exit(-1); } else if (fpid1 == 0) { //dup2(fd[1], STDOUT_FILENO); close(fd[1]); //close(fd[0]); // File pointer for the file that'll be written to FILE * file; // freopen() redirects stdin to args[nargs - 1], // which contains the name of the file we're writing to file = freopen(args[nargs - 1], "w+", stdin); // If we include this line, the functionality works //execvp(args[0],args); // We're done writing to the file, so close it fclose(file); // We're done using the pipe, so close it (unnecessary?) //close(fd[1]); } else { // Wait for the child process to terminate wait(0); printf("This is the parent\n"); // Connect write end of pipe (fd[1]) to standard output dup2(fd[1], STDOUT_FILENO); // We don't need the read end, so close it close(fd[0]); // args[0] contains the command "ls", which is // what we want to execute execvp(args[0], args); // This is just a test line I was using before to check // whether anything was being written to stdout at all printf("Exec was here\n"); } // This is here to make sure program execution // doesn't continue into the original code, which // currently causes errors due to incomplete functionality exit(0); /* check if async call */ printf("Async call part\n"); if(!strcmp(args[nargs-1], "&")) { async = 1; args[--nargs] = 0; } else async = 0; pid = fork(); if(pid == 0) { /* child process */ execvp(args[0], args); /* return only when exec fails */ perror("exec failed"); exit(-1); } else if(pid > 0) { /* parent process */ if(!async) waitpid(pid, NULL, 0); else printf("this is an async call\n"); } else { /* error occurred */ perror("fork failed"); exit(1); } } int main (int argc, char* argv []) { char cmdline[BUFSIZE]; for(;;) { printf("COP4338$ "); if(fgets(cmdline, BUFSIZE, stdin) == NULL) { perror("fgets failed"); exit(1); } execute(cmdline) ; } return 0; }
So, what's the problem? Simple: the code above creates a file with the expected name, i.e. the name provided in the command line, which gets placed at args[nargs - 1]. For instance, running the program and then typing
ls > test.txt
Creates a file called test.txt... but it doesn't actually write anything to it. I did manage to get the program to print garbage characters to the file more than a few times, but this only happened during bouts of desperate hail mary coding where I was basically just trying to get the program to write SOMETHING to the file.
I do think I've managed to narrow down the cause of the problems to this area of the code:
else if (fpid1 == 0) { printf("This is the child.\n"); //dup2(fd[1], STDOUT_FILENO); close(fd[1]); //close(fd[0]); // File pointer for the file that'll be written to FILE * file; // freopen() redirects stdin to args[nargs - 1], // which contains the name of the file we're writing to file = freopen(args[nargs - 1], "w+", stdout); // If we include this line, the functionality works //execvp(args[0],args); // We're done writing to the file, so close it fclose(file); // We're done using the pipe, so close it (unnecessary?) //close(fd[1]); } else { // Wait for the child process to terminate wait(0); printf("This is the parent\n"); // Connect write end of pipe (fd[1]) to standard output dup2(fd[1], STDOUT_FILENO); // We don't need the read end, so close it close(fd[0]); // args[0] contains the command "ls", which is // what we want to execute execvp(args[0], args); // This is just a test line I was using before to check // whether anything was being written to stdout at all printf("Exec was here\n"); }
More specifically, I believe the problem is with the way I'm using (or trying to use) dup2() and the piping functionality. I basically found this out by process of elimination. I spent a few hours commenting things out, moving code around, adding and removing test code, and I've found the following things:
1.) Removing the calls to dup2() and using execvp(args[0], args) prints the result of the ls command to the console. The parent and child processes begin and end properly. So, the calls to execvp() are working properly.
2.) The line
file = freopen(args[nargs - 1], "w+", stdout)
Successfully creates a file with the correct name, so the call to freopen() isn't failing. While this doesn't immediately prove that this function is working properly as it's written now, consider fact #3:
3.) In the child process block, if we make freopen redirect to the output file from stdin (rather than stdout) and uncomment the call to execvp(args[0], args), like so:
// freopen() redirects stdin to args[nargs - 1], // which contains the name of the file we're writing to file = freopen(args[nargs - 1], "w+", stdin); // If we include this line, the functionality works execvp(args[0],args);
and run the program, then it works and result of the ls command is successfully written to the output file. Knowing this, it seems pretty safe to say that freopen() isn't the problem either.
In other words, the only thing I haven't been able to successfully do is pipe the output of the execvp() call that's done in the parent process to stdout, and then from stdout to the file using freopen().
Any help is appreciated. I've been at this since 10 AM yesterday and I'm completely out of ideas. I just don't know what I'm doing wrong. Why isn't this working?
-
Powershell Get-PrinterPort Invalid Query
Having trouble with this function something with the Get-PrinterPort erroring out.
Error Message(s) below
Get-PrinterPort : Invalid query At line:10 char:16 + $printer = Get-PrinterPort -Name $test | ft DeviceURL | out-strin ... + ~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : InvalidArgument: (MSFT_PrinterPort:ROOT/StandardCimv2/MSFT_PrinterPort) [Get-PrinterPort], CimException + FullyQualifiedErrorId : HRESULT 0x80041017,Get-PrinterPort` Exception calling "Substring" with "2" argument(s): "Length cannot be less than zero. Parameter name: length" At line:16 char:5 + $printhostname = $printer.Substring(0, $pos) + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : NotSpecified: (:) [], MethodInvocationException + FullyQualifiedErrorId : ArgumentOutOfRangeException`
This is the code, I've narrowed it down to a suspected issue with the Get-PrinterPort -Name part, the guides say it takes a string[] but doesn't like the output from out-string. Any tips or blinding errors?
function Get-HostNameFromPrinterName { $servername = Read-Host -Prompt "Enter the name of the Printer" $WSD = (Get-WmiObject -class Win32_Printer | where Name -match $servername | select PortName) | out-string $pos = $WSD.IndexOf("W") $WSD = $WSD.Substring($pos) $pos = $WSD.IndexOf("`n") $WSD = $WSD.Substring(0, $pos) $printer = Get-PrinterPort -Name $WSD | ft DeviceURL | out-string $pos = $printer.IndexOf("/") $printer = $printer.Substring($pos+1) $pos = $printer.IndexOf("/") $printer = $printer.Substring($pos+1) $pos = $printer.IndexOf("/") $printhostname = $printer.Substring(0, $pos) write-host $printhostname }
Also please forgive any formatting errors :p
EDIT: After testing the variable type returns system.string
This program does the same thing however it works fine.
function Get-HostNameFromWSD { $WSD = Read-Host -Prompt 'Input WSD' $printer = Get-PrinterPort -name $WSD | ft DeviceURL | out-string $pos = $printer.IndexOf("/") $printer = $printer.Substring($pos+1) $pos = $printer.IndexOf("/") $printer = $printer.Substring($pos+1) $pos = $printer.IndexOf("/") $printhostname = $printer.Substring(0, $pos) write-host $printhostname }
This variable also returns system.string. Not sure where the error lies.
-
Sum of values in a foreach loop php
I have a response like this:
"data": [ { "pay": "2010000", }, { "pay": "3010000", }, { "pay": "3920000", }, ] foreach ($data as $data) { $sum += $data['pay']; array_push($newArr, array( "finalResult" => '0', ) ); }
I want to get (individual pay divided by sum of all pay) results and should push this value into array. I have a foreach loop where I'm trying to get the final result. But the final result array is showing incorrect data. Is there anything I'm missing?
I tried this with two foreach loops like this. But I'm getting wrong result
foreach ($newArr as $newArr_key => $newArr_value) { if ($sum != 0) { $finalResult = $data['pay']/ $sum; if (isset($finalResult) && $finalResult != '') { $newArr[$newArr_key]['finalResult'] = $finalResult; } } else { $finalResult = 'Division by Zero'; } }
-
How to graph a nested array's frequency of words?
I have a dataset in lists nested within a
dict
. The value names are the unix epoch time in this, and the value is a list of lists, each one containing an amount and the data that is occurring that amount of times.This is a JSON array that was spat out by my program:
{ "1524149740": [ [7, "meme of the"], [6, "when you see"], [6, "of the week"], [5, "when you realize"], [5, "the eel memes"], [4, "lies of the"], [3, "you realize that"], [3, "when your friend"], [3, "when someone asks"], [3, "the meme of"] ], "1524155383": [ [9, "meme of the"], [8, "of the week"], [7, "the eel memes"], [6, "when you see"], [6, "when you realize"], [4, "you realize that"], [4, "when your friend"], [4, "the meme of"], [4, "lies of the"], [3, "you try to"] ], "1524153849": [ [9, "meme of the"], [8, "of the week"], [7, "the eel memes"], [6, "when you see"], [6, "when you realize"], [4, "you realize that"], [4, "when your friend"], [4, "the meme of"], [4, "lies of the"], [3, "you try to"] ], "1524152316": [ [9, "meme of the"], [8, "of the week"], [7, "the eel memes"], [6, "when you see"], [6, "when you realize"], [4, "you realize that"], [4, "the meme of"], [4, "lies of the"], [3, "you try to"], [3, "which has no"] ] }
What I need to do is graph the percentage of each set of 3 words at that epoch time. How could I do this?
Preferably using a line graph.