• Hey, guest user. Hope you're enjoying NeoGAF! Have you considered registering for an account? Come join us and add your take to the daily discourse.

Programming |OT| C is better than C++! No, C++ is better than C

Chris R

Member
Had a good day today. Sped up a critical algorithm by almost 3 orders of magnitude

Always a great feeling.

It's like "Shit, I had to have missed something, this used to take 5+ seconds to run and now it's done in 50ms" then slowly you realize, nope, shit was just slow/badly written to begin with :\

UPDATE dTable SET device = {0}

Your query is bad. This UPDATE is setting EVERYTHING to whatever {0} is since you have no where clause.
 

Lister

Banned
Here is my code. Same problem as before, the values are being overwritten to whatever the last row's value is.

Example:

If my initial column is:
1
2
3
4

And I am writing a method, say to multiple the existing values by 2 and update the table, my result set should be
2
4
6
8

But I am getting
8
8
8
8

This is my method as it stands:
Code:
private void extractBitsFromWordAndUpdate() 
{
  if(this.con.State != ConnectionState.Open) 
  {
    this.conn.Open(); 
   }
   PacketHelper helper = null; 
   String query = "SELECT device FROM dTable";
   OdbcCommand command = new OdbcCommand(query, this.conn);
    OdbcDataReader reader = null;
    reader = command.ExecuteReader();
    while(reader.Read())
     {
       helper = PacketHelper();
       int extractedVal = Convert.toInt32(reader["device"]); // col name
       helper.assembleWord(extractedVal); // all this does is call a getter() for a member variable
       }
       reader.Close();
       String update = "UPDATE dTable SET device = {0}",
       helper.getKeyPad()); // what I want to change the value to. This method is fine. 
       OdbcCommand commandTwo = new OdbcCommand(update, this.conn);
       commandTwo.ExecuteNonQuery();
       this.conn.Close();
}
 }

Again, written in C# and the problem is the rows are only updating based on the last row's value.

It looks like you are iterating over the recordset and calling the helper method that does the shifting, but then setting every record's "device" column to whatever the LAST output was with the following SQL:

"UPDATE dTable SET device = {0}", This will update every row's device column to only ONE value, in this case, the last value processed in the while loop.

What you probably want to do is gather all the values in a list or array, and THEN update each row separately with the appropriate value.

I usually use entity and that would allow me to do both things at the same time, something like this:

Code:
      var query = from row in rows      
      select row;
      foreach (var row in query)
      {
          row.device = helper.assembleWord(row.device);
      }
       data.SaveChanges();

But you should get the gist. You need to grab the value, and then either write the updated value to the database right there and then (or as part of a transaction in say entity), or hold the values and write to each row seperately later. This could be done with seperate update statements with a WHERE clause. Not sure if that's optimal in terms of efficiency though.
 
It looks like you are iterating over the recordset and calling the helper method that does the shifting, but then setting every record's "device" column to whatever the LAST output was with the following SQL:

"UPDATE dTable SET device = {0}", This will update every row's device column to only ONE value, in this case, the last value processed in the while loop.

What you probably want to do is gather all the values in a list or array, and THEN update each row separately with the appropriate value.

I usually use entity and that would allow me to do both things at the same time, something like this:

Code:
      var query = from row in rows      
      select row;
      foreach (var row in query)
      {
          row.device = helper.assembleWord(row.device);
      }
       data.SaveChanges();

But you should get the gist. You need to grab the value, and then either write the updated value to the database right there and then (or as part of a transaction in say entity), or hold the values and write to each row seperately later. This could be done with seperate update statements with a WHERE clause. Not sure if that's optimal in terms of efficiency though.

Would throwing the update query in the whole loop
Work?
 
Or in the while loop, throw everything in a List, close the while loop. For loop through the list and assign the values with the helper method and put the the update query inside the for loop
 

Zoe

Member
Would throwing the update query in the whole loop
Work?

No, you need to uniquely identify which row you are updating.

Even if you did
Code:
where device = extractedVal
you run the risk of updating a row multiple times if there's a value further down the set that equals what you just updated it to.
 

Zoe

Member
Or in the while loop, throw everything in a List, close the while loop. For loop through the list and assign the values with the helper method and put the the update query inside the for loop

You would need a dictionary where the original device is the key and the bit-shifted result is the value.
 
No, you need to uniquely identify which row you are updating.

Even if you did
Code:
where device = extractedVal
you run the risk of updating a row multiple times if there's a value further down the set that equals what you just updated it to.
I think my second response sounds correct, with the List
 
Eh.... What you *really* need is to use parameters instead of named columns, and set the ParamDirection to ParameterDirection.InputOutput.

Then you can just iterate over each row and assign the updated value.
 

Koren

Member
Yea, instead of storing Xs in your hash table, store pointers to some object that contains X along with an optional hash value. The hash function then either computes hash of X and saves it in the encapsulating record or returns the previously computed hash.
That's what I've done, I'm relieved that it seems sound ^_^

Without this you essentially get N^2 hash computations as the table continually grows and triggers full rehashes
If you get n^2 computations when you add N elements to a hashtable, you have a big problem ;)

It should be O(n)... Around 2.n if you double the size of the table each time you need a larger one.

For example, for 200 values :

first 10 hashed
reach 10, resize, 10 rehashed

10 more new hashs
reach 20, resize, 20 rehashed

20 more new hashs
reach 40, resize, 40 rehashed

40 more new hashs
reach 80, resize, 80 rehashed

80 more new hashs
reach 160, resize, 160 rehashed

40 more new hash

10 are hased 6 times, 20, 5 times, 40, 3 times, 80 twice, 40 once. That's 480 hashs...


I'll definitively take the 2x speed increase in a critical part, but if you have a change in complexity, there's something wrong with you resizing mechanism, no?
 

Zoe

Member
Eh.... What you *really* need is to use parameters instead of named columns, and set the ParamDirection to ParameterDirection.InputOutput.

Then you can just iterate over each row and assign the updated value.

You still need separate select and update statements. If he doesn't have any kind of unique identifier in the rows, that could be a problem.
 
That's what I've done, I'm relieved that it seems sound ^_^


If you get n^2 computations when you add N elements to a hashtable, you have a big problem ;)

It should be O(n)... Around 2.n if you double the size of the table each time you need a larger one.

For example, for 200 values :

first 10 hashed
reach 10, resize, 10 rehashed

10 more new hashs
reach 20, resize, 20 rehashed

20 more new hashs
reach 40, resize, 40 rehashed

40 more new hashs
reach 80, resize, 80 rehashed

80 more new hashs
reach 160, resize, 160 rehashed

40 more new hash

10 are hased 6 times, 20, 5 times, 40, 3 times, 80 twice, 40 once. That's 480 hashs...


I'll definitively take the 2x speed increase in a critical part, but if you have a change in complexity, there's something wrong with you resizing mechanism, no?

Suppose you've got a stupid hash table that grows every time you insert.

Insert 1 item: 1 hash computation
Insert 1 more item: 2 hash computations
Insert 1 more item: 3 hashes

Total number of hashes after N inserts is 1 + 2 + ... + N = (N^2 + N)/2
 
You still need separate select and update statements. If he doesn't have any kind of unique identifier in the rows, that could be a problem.
The table has a primary key (just a index) but a particular device can show up more than once but the values will be different. Like signal 1 can show up twice, first instance is a value of 4; the next a 6.
 

Zoe

Member
It's worth noting in my application that say 128 is 2, every instance of 128 will be a 2 as well, not just the first.

The table has a primary key (just a index) but a particular device can show up more than once but the values will be different. Like signal 1 can show up twice, first instance is a value of 4; the next a 6.

So think about how this could be problematic if you don't make use of the unique ID:
Code:
ID	Device
1	1
2	2
3	1
4	3
5	4

In the first iteration of the loop, you will bit-shift all instances of "1" in the table. So then what will happen when your loop hits one of those devices that's already been updated? It's going to bit-shift that device again.

Edit: brain fart, it's going to be problematic if you have any devices that equal any results you've already hit. So ID's 1 and 3 will update to 2. Then when you hit the second iteration of the loop, all instances of 2 will be bit-shifted, so now ID's 1, 2, and 3 will all update to 8.

So in your loop you'll want to store both the ID and the Device. In your update, you'll want to
Code:
update table set device = <result> where ID = <id>
 
Suppose you've got a stupid hash table that grows every time you insert.

Insert 1 item: 1 hash computation
Insert 1 more item: 2 hash computations
Insert 1 more item: 3 hashes

Total number of hashes after N inserts is 1 + 2 + ... + N = (N^2 + N)/2

So I did the math, it depends on your growth factor. If you double every time then this cancels out the square component from the aforementioned equation, and you end up with 2N.

BTW, since it seems like you're either a college professor, TA, or graduate student, that would make a good question for an algorithms class :)

"How does the growth factor of a hash table affect the complexity of inserting with respect to the hash function?"
 
So think about how this could be problematic if you don't make use of the unique ID:
Code:
ID	Device
1	1
2	2
3	1
4	3
5	4

In the first iteration of the loop, you will bit-shift all instances of "1" in the table. So then what will happen when your loop hits one of those devices that's already been updated? It's going to bit-shift that device again.

Edit: brain fart, it's going to be problematic if you have any devices that equal any results you've already hit. So ID's 1 and 3 will update to 2. Then when you hit the second iteration of the loop, all instances of 2 will be bit-shifted, so now ID's 1, 2, and 3 will all update to 8.

So in your loop you'll want to store both the ID and the Device. In your update, you'll want to
Code:
update table set device = <result> where ID = <id>

So something as basic as
Code:
private void extractBitsFromWordAndUpdate() 
{
  if(this.con.State != ConnectionState.Open) 
  {
    this.conn.Open(); 
   }
   PacketHelper helper = null; 
   String query = "SELECT signalID, device FROM dTable";
   OdbcCommand command = new OdbcCommand(query, this.conn);
    OdbcDataReader reader = null;
    reader = command.ExecuteReader();
    while(reader.Read())
     {
       helper = PacketHelper();
       int extractedVal = Convert.toInt32(reader["device"]); // col name
       int deviceID = Convert.ToInt32(reader["deviceID"]);  // device id
       helper.assembleWord(extractedVal); // all this does is call a getter() for a member variable
       }
       reader.Close();
       String update = "UPDATE dTable SET device {0} WHERE device = " + extractedVal + " AND signalID = " + deviceID;
       helper.getKeyPad()); // what I want to change the value to. This method is fine. 
       OdbcCommand commandTwo = new OdbcCommand(update, this.conn);
       commandTwo.ExecuteNonQuery();
       this.conn.Close();
}
 
Bah, because I just can't leave well enough alone. I think it only depends on the growth factor being multiplicative. Even if you grow by 1.01x every time it still seems to work out to O(N) in the long run. Weird, I certainly don't find this intuitive
 
Bah, because I just can't leave well enough alone. I think it only depends on the growth factor being multiplicative. Even if you grow by 1.01x every time it still seems to work out to O(N) in the long run. Weird, I certainly don't find this intuitive
Here's what I'm getting.

Consider (1) the number of elements in a hashtable at a given resize and (2) the total number of hashes you have to make upon resize. For a table with resize ratio m, that looks like this:

m | m
m^2 | (m^² - m) + m^2 [you hashed the new stuff, then everything]
m^3 | (m^3 - m^2) + m^3
... | ...
m^p | (m^p - m^(p-1)) + m^p

Where p = log_n m. To get total hashes we'd sum the right column. But notice that the middle term cancels out with one of the terms in the above row. So the whole thing cancels out to m^p + a power series (m^2 ... m^p).

Which turns into m^p + (m^2 * (m^p - 1))/(m - 1).

so given m^p = n, that's a linear function of m.
 

Koren

Member
Suppose you've got a stupid hash table that grows every time you insert.

Insert 1 item: 1 hash computation
Insert 1 more item: 2 hash computations
Insert 1 more item: 3 hashes

Total number of hashes after N inserts is 1 + 2 + ... + N = (N^2 + N)/2
Indeed... But I would consider this as a "problem" with the hash table. ^_^

It would be a big improvement.

BTW, since it seems like you're either a college professor, TA, or graduate student, that would make a good question for an algorithms class :)

"How does the growth factor of a hash table affect the complexity of inserting with respect to the hash function?"
I don't remember seeing it for hash tables, but it's not an uncommon one for appends on resizable tables. The maths are the same.

If you really want to be annoying, you take table sizes to be the values of a math sequence, like Fibonacci... No practical interests, but sometimes problems here are designed by math teachers ;)

Edit : it's still O(n) for Fibonacci for quite obvious reasons if you know u_n+1/u_n has a golden ratio limit, but it's a longer proof for people not accustomed with the maths.

Bah, because I just can't leave well enough alone. I think it only depends on the growth factor being multiplicative. Even if you grow by 1.01x every time it still seems to work out to O(N) in the long run. Weird, I certainly don't find this intuitive
I fully agree, it feels strange. But if you add any fixed size, it's O(n^2), if you use any multiplicative factor it's O(n).

Depending on the values, O(n^2) can be faster than O(n) for practical n, though. But a ~2x resizing gives good results.

The exact factor is subject to debates. 2 and the golden ratio are the most common I think

koren is an assistant professor
It's hard to translate our system into US "ranks", but I'm currently teaching ~20 y.o. students, yes.
 
I simply gave up on dual boots, especially on laptops. But even installing Linux alone is sometimes annoying as hell (or virtually impossible).

I hate UEFI and everything hardware makers do to basically support Microsoft.

UEFI, while it has some things that I guess you could argue are to "support windows", also brings with it many other advantages, such as support for large hard drives, faster boot times, and more modern firmware interfaces.

Secure Boot, which is what I assume you're referring to, is only one very small component of the entire feature set of UEFI

Doesn't Ubuntu also use Secure Boot these days?
 

Koren

Member
Secure Boot, which is what I assume you're referring to, is only one very small component of the entire feature set of UEFI
Yes, I'm talking about secure boot, I should have been more precise.

Though I believe there's also problems with other parts of UEFI. Can you even do an USB bootable device that support both UEFI and non-UEFI for both 32 and 64 bit systems? I think you can't... Or at least, I still haven't been able to do it (I've built ISOs with Debian-live, but since UEFI surfaced, I haven't been able to build a key that works on any computer)

Doesn't Ubuntu also use Secure Boot these days?
Well, somehow, but apparently sometimes it works, sometimes it doesn't (on my mini-laptop, you need to hack the thing a lot to be able to use Ubuntu... if you ever manage to do it)

But still, I stay away from Ubuntu, I really don't like the distribution. I prefer using a Mint DE by very, very far. Ubuntu doesn't equal Linux... So that doesn't really solve anything.
 

Koren

Member
I'm reluctant to ask this, but... I simply don't have time to do this properly...

I need to be able to put a set of pages online, that only a set of users can access. I have a set of logins/passwords for this.

I could have done this by htaccess, but some pages are php and I need to be able to access the login from the php scripts (to access either specific files or do sql queries, still not sure).

Can someone suggest me a dummy-proof example of setting a couple of pages with authentication and how to use credentials after that?


Bonus point if there's a way to update the password. But given the time frame, it will be build with tape everywhere, so anything will do, really, as soon as it's easy to understand for someone that used quite often html / css / php, javascript from time to time, but nearly always relied on htaccess for "security".


Edit : is this
https://code.tutsplus.com/tutorials/how-to-create-a-phpmysql-powered-forum-from-scratch--net-10188
a decent way to have authentication with a "decent" security? I'm can work with this, if $_SESSION is a decent way to store credentials for a session...
 
I'm confused as to why this program does strchr instead of strtok. Any insight?

Code:
	//read data string from client 
	if(recv(connection, buffer, sizeof(buffer), 0) == -1){
		fprintf(stderr, "Error receiving data from client\n");
		exit(1);
	}
	
	buffer[BUFFSIZE] = 0;
	
	command = buffer;
	char *temp;
	temp = strchr(buffer, ' '); 
	*temp = 0; 
	
	
	hostname = temp + 1;
	temp = strchr(hostname, ' '); 
	*temp = 0;
	
	dataPort = temp + 1; 
	temp = strchr(dataPort, ' ');
	*temp = 0;
	
	filefetch= temp + 1;
	temp = strchr(filefetch, ' ');

dataPort, hostname, filefetch, and command are simply char pointers.

As far as I understand the client sends a string. This function gets it using recv. Then breaks it apart like this because the string is space delimited.

Is there any benefit to doing it this way over strtok?
 

Lister

Banned
I'm reluctant to ask this, but... I simply don't have time to do this properly...

I need to be able to put a set of pages online, that only a set of users can access. I have a set of logins/passwords for this.

I could have done this by htaccess, but some pages are php and I need to be able to access the login from the php scripts (to access either specific files or do sql queries, still not sure).

Can someone suggest me a dummy-proof example of setting a couple of pages with authentication and how to use credentials after that?


Bonus point if there's a way to update the password. But given the time frame, it will be build with tape everywhere, so anything will do, really, as soon as it's easy to understand for someone that used quite often html / css / php, javascript from time to time, but nearly always relied on htaccess for "security".


Edit : is this
https://code.tutsplus.com/tutorials/how-to-create-a-phpmysql-powered-forum-from-scratch--net-10188
a decent way to have authentication with a "decent" security? I'm can work with this, if $_SESSION is a decent way to store credentials for a session...

There are a lot of third party authentication systems out there and they are the best way to work with security. I really don't recommend trying to roll out your own authentication system.

Google, Facebook, Twitter all offer Open ID for authentication, as does Microsoft (they have a free tier of azure B2C which allows you to use local accounts as well as other third party providers, not to mention Active directory, though of course those solutions are geared towards .net apps.

As for the article, I would note that you deinfitely want to salt and hash the passwords and store the salt along with the password in the table. Still, I'd recommend just usinga third party service in this day and age, especially is security is important to you.
 

Koren

Member
There are a lot of third party authentication systems out there and they are the best way to work with security. I really don't recommend trying to roll out your own authentication system.

Google, Facebook, Twitter all offer Open ID for authentication, as does Microsoft (they have a free tier of azure B2C which allows you to use local accounts as well as other third party providers, not to mention Active directory, though of course those solutions are geared towards .net apps.
I know, but honestly, it's too much dependancies and too complex a solution for this. And I don't have time for this.

Beside, from a philosophical point of view, I don't think third party is satisfying, and I don't like delegating authentication to Microsoft, Google, Apple, Facebook, Twitter or Amazon...

I can't ask the users to have an account there either (especially when they'll use the website once and for 5 minutes)

As for the article, I would note that you deinfitely want to salt and hash the passwords and store the salt along with the password in the table.
Yes, salt was a given... although I really don't think it'll be an issue there...

Still, I'd recommend just usinga third party service in this day and age, especially is security is important to you.
Depends how you define "important". I don't want an obvious weakness... There will be phone numbers and emails stored there, and I'd like to avoid them exposed.

But the website will be live for ~30-40 days (and not public, in theory), so as long as there's no obvious and simple weaknesses, it's fine for me.

Many thanks for the advices, in any case.
 
I'm confused as to why this program does strchr instead of strtok. Any insight?

Code:
	//read data string from client 
	if(recv(connection, buffer, sizeof(buffer), 0) == -1){
		fprintf(stderr, "Error receiving data from client\n");
		exit(1);
	}
	
	buffer[BUFFSIZE] = 0;
	
	command = buffer;
	char *temp;
	temp = strchr(buffer, ' '); 
	*temp = 0; 
	
	
	hostname = temp + 1;
	temp = strchr(hostname, ' '); 
	*temp = 0;
	
	dataPort = temp + 1; 
	temp = strchr(dataPort, ' ');
	*temp = 0;
	
	filefetch= temp + 1;
	temp = strchr(filefetch, ' ');

dataPort, hostname, filefetch, and command are simply char pointers.

As far as I understand the client sends a string. This function gets it using recv. Then breaks it apart like this because the string is space delimited.

Is there any benefit to doing it this way over strtok?

strchr is ridiculously fast since it can be vectorized. strtok can't
 
Thanks guys.

Also just to make sure I understand. If someone sent

"Delete host@host 1337 file.txt"

The result would be:

Command = pointer to D
The string then becomes Delete0host@host 1337 file.txt

Hostname = pointer to h
The string then becomes Deletehost@host@ 1337 file.txt

Dataport = pointer to 1

filefetch = pointer to f

right?

However this seems... bad?

If after that last line of code I did:

printf("command: %s, data_port: %s, filename: %s\n", command, data_port, filefetch);

I'd get:
Code:
command: [email]Delete0host@host013370file.txt[/email], data_port: 13370file.txt, filename: file.txt
 
Thanks guys.

Also just to make sure I understand. If someone sent

"Delete host@host 1337 file.txt"

The result would be:

Command = pointer to D
The string then becomes Delete0host@host 1337 file.txt

Hostname = pointer to h
The string then becomes Deletehost@host@ 1337 file.txt

Dataport = pointer to 1

filefetch = pointer to f

right?

However this seems... bad?

If after that last line of code I did:

printf("command: %s, data_port: %s, filename: %s\n", command, data_port, filefetch);

I'd get:
Code:
command: [email]Delete0host@host013370file.txt[/email], data_port: 13370file.txt, filename: file.txt

Edit: Ignore my original post, I guess I should read the code :)

Yea, looks right. Why does it seem bad out of curiosity? If anything's bad, it's that strchr() returns a char* even though you gave it a const char*. WTF is that about? Never realized that function did that.
 
Edit: Ignore my original post, I guess I should read the code :)

Yea, looks right. Why does it seem bad out of curiosity? If anything's bad, it's that strchr() returns a char* even though you gave it a const char*. WTF is that about? Never realized that function did that.

It seems bad if the purpose is to split the string into its individual words and use those words for later.

You can't actually print the host name using this method. You'd print that weird string.

I think it may actually be better to use strtok here.
 
It seems bad if the purpose is to split the string into its individual words and use those words for later.

You can't actually print the host name using this method. You'd print that weird string.

I think it may actually be better to use strtok here.

Oh wait, I missed something. No it's not going to print the character '0'. The number 0 is a null terminator. The character 0 actually has the value 48 (hex 0x30). When you say *temp = 0 you're modifying the original input buffer to contain null terminators, so when you print "command", it's just going to print "Delete", because the very next character is a null terminator.
 
Oh wait, I missed something. No it's not going to print the character '0'. The number 0 is a null terminator. The character 0 actually has the value 48 (hex 0x30). When you say *temp = 0 you're modifying the original input buffer to contain null terminators, so when you print "command", it's just going to print "Delete", because the very next character is a null terminator.

ohhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh.

Holy fuck that's awesome.

Thanks cpp.
 
ohhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh.

Holy fuck that's awesome.

Thanks cpp.

BTW, there's multiple "better" ways to do this.

1) Use C++ and store the input in a std::string. Then use str.find_first_of(' ') and str.substr to extract the various tokens, then print them using std::cout.

2) If your compiler supports C++17, an improvement over #1 is to use std::string_view. Normally std::string::substr() will make a copy so that it can null terminate the substring, but when you use std::string_view this isn't necessary, so it's slightly more efficient.

3) Use the super obscure %.*s printf format specifier. When you do this, instead of just specifying the string to print, you also specify the number of characters to print. So you could do something like this:

Code:
buffer[BUFFSIZE] = 0;
const char *command = buffer;

const char *temp;
temp = strchr(buffer, ' '); 
int command_len = temp - buffer;

hostname = temp + 1;
temp = strchr(hostname, ' '); 
int hostname_len = temp - hostname;

dataPort = temp + 1; 
temp = strchr(dataPort, ' ');
int port_len = temp - dataPort;

filefetch = temp + 1;
temp = strchr(filefetch, ' ');
int filefetch_len = temp - filefetch;

printf("command: %.*s, hostname: %.*s, data_port: %.*s, filename: %.*s\n", command_len, command, hostname_len, hostname, port_len, data_port, filefetch_len, filefetch);

The nice thing about this is that it doesn't modify your input buffer, which is generally considered a pretty obnoxious thing to do.
 
Out of curiosity, why, in a case such as this?
Maybe it's just the idealist in me, but if an operation doesn't *need* to modify its input then it shouldn't, imo. Conceptually, you don't *need* to modify a string in order to print out pieces of it, and the fact that people do is basically a hack to make printf work. That's the language making you work around it, rather than making the language work for you. Plus it makes the code more brittle and hard to reason about, is not reentrant, etc.

Obviously you don't care about this kind of thing for a throwaway program, but I figure if you can do it right, then you should do it right.


It's not the case in ISO C++...

Ok, I guess there is hope for the world. First link I clicked was this: http://man7.org/linux/man-pages/man3/strchr.3.html which shows it accepting a const char* and returning a char*. Didn't look further
 

BeforeU

Oft hope is born when all is forlorn.
Can you guys suggest a website where i can practice more coding?

I have done the tutorials and stuff but want to apply the knowledge now. So looking for a place where I can find tons of problems to practice. Algorithms and data structures are my weak point. Just confuses me.
 
Can you guys suggest a website where i can practice more coding?

I have done the tutorials and stuff but want to apply the knowledge now. So looking for a place where I can find tons of problems to practice. Algorithms and data structures are my weak point. Just confuses me.
codingbat is a good resource. Also, best way to learn is to pick a project you'd like to try. You'll most likely be dealing with data and you can pick your own structures to hold and manipulate.
 
Sr. developers here naming variable stringOne, stringTwo... and not using encapsulation. I felt like a douche but I rewrote the existing code with accessors and proper variable names.
 

Koren

Member
Maybe it's just the idealist in me, but if an operation doesn't *need* to modify its input then it shouldn't, imo
I feel the same... though it depends where the code sits, and what it's doing.

If you write a function that read data (from file or stdout) and must returns a set of char* (or print those and do nothing more with those), I think it's fine. OTOH, if you write a function that receive a buffer and has to print it in parts, I fully agree with you.

It's probably a matter of where the piece of code is, in fact...

Ok, I guess there is hope for the world. First link I clicked was this: http://man7.org/linux/man-pages/man3/strchr.3.html which shows it accepting a const char* and returning a char*. Didn't look further
Well, I think it IS sometimes the case. I never really understood the reason. But looking at my string.h, I get:
Code:
__BEGIN_NAMESPACE_STD
/* Find the first occurrence of C in S.  */
#ifdef __CORRECT_ISO_CPP_STRING_H_PROTO
extern "C++"
{
extern char *strchr (char *__s, int __c)
     __THROW __asm ("strchr") __attribute_pure__ __nonnull ((1));
extern const char *strchr (const char *__s, int __c)
     __THROW __asm ("strchr") __attribute_pure__ __nonnull ((1));

# ifdef __OPTIMIZE__
__extern_always_inline char *
strchr (char *__s, int __c) __THROW
{
  return __builtin_strchr (__s, __c);
}

__extern_always_inline const char *
strchr (const char *__s, int __c) __THROW
{
  return __builtin_strchr (__s, __c);
}
# endif
}
#else
extern char *strchr (const char *__s, int __c)
     __THROW __attribute_pure__ __nonnull ((1));
#endif
So... it depends.

It's one of those reasons that makes me lean towards a C++ compiler even when I basically only write "C" code (but well... overloading in C, even in X11...)

Sr. developers here naming variable stringOne, stringTwo... and not using encapsulation. I felt like a douche but I rewrote the existing code with accessors and proper variable names.
Feels like sane behavior to me... ;)

At least, when the language is designed this way (each time I see java-styled accessors in Python code, my eyes burn)
 
Well, I think it IS sometimes the case. I never really understood the reason. But looking at my string.h, I get:
Code:
__BEGIN_NAMESPACE_STD
/* Find the first occurrence of C in S.  */
#ifdef __CORRECT_ISO_CPP_STRING_H_PROTO
extern "C++"
{
extern char *strchr (char *__s, int __c)
     __THROW __asm ("strchr") __attribute_pure__ __nonnull ((1));
extern const char *strchr (const char *__s, int __c)
     __THROW __asm ("strchr") __attribute_pure__ __nonnull ((1));

# ifdef __OPTIMIZE__
__extern_always_inline char *
strchr (char *__s, int __c) __THROW
{
  return __builtin_strchr (__s, __c);
}

__extern_always_inline const char *
strchr (const char *__s, int __c) __THROW
{
  return __builtin_strchr (__s, __c);
}
# endif
}
#else
extern char *strchr (const char *__s, int __c)
     __THROW __attribute_pure__ __nonnull ((1));
#endif

lol at "#ifdef __CORRECT_ISO_CPP_STRING_H_PROTO".
 

Koren

Member
If you want a good troll, just try to *really* understand rvalue references and move semantics in C++.
The only issue I have with C++ is that I feel I'll NEVER fully understand the language.

It's kinda annoying, because I don't feel like that with other languages. Maybe Java is the same, but I'll never want to master Java, I'm happy staying away from it as much as I can.

There's plently of languages where there's still plently of things I have to understand, like Scala, but I feels like it's a finite set, and evolving slowly. In Python, the moments where I am "I didn't know that" are less and less common.

But I C++, expanding the mechanisms seems like a sport (partly to circumvent issues brought by previous, imperfect mechanisms) and the expension, like the universe, is faster than I can learn/travel...

I've learn some move semantics just to be able to avoid useless copying in common cases, but it reached the stack of "things I should study further in the slight chance I find the time and I lost my mind"...
 

phisheep

NeoGAF's Chief Barrister
Can you guys suggest a website where i can practice more coding?

I have done the tutorials and stuff but want to apply the knowledge now. So looking for a place where I can find tons of problems to practice. Algorithms and data structures are my weak point. Just confuses me.

I'm having a real good time on Codefights. The arcade section starts off very basic, but there's some juicy problems later on, and it does seem to do well at diving into trickier bits of the languages.
 
Top Bottom